2010/10/19 <arnaud.champion(a)devatom.fr>:
Hi,
here are 2 patches for C# libvirt bindings.
These patches create a new solution/project couple for Visual Studio 2010
with also a sample code and a solution/project couple for MonoDevelop with a
sample code also.
The sample code have been tested under .Net/Windows, Mono/Windows and
Mono/Linux. And it works, the sample code consist of the using au
virConnectOpenAuth and callback handling. It connect to a URI (I have made
my tests with ESX hypervisor only) and list domains in a listbox.
So, to summarize, code work under linux or windows, the binary library name
depends of a project directive (a kind of pragma). When the directive
WINDOWS is declared, DllImport will try to find "libvirt-0.dll" (for
windows) otherwise it looks for "libvirt.so.0" (for linux). For now, in the
same manner, when the directive WINDOWS is declared, we find _strdup in
"msvcrt.dll" otherwise we look in "libc.so.6".
This makes the resulting binary platform dependent. I asked a friend
about this and he suggested to use Mono's dllmap feature [1]. It
allows you to stick with [DllImport("libvirt-0.dll")] in the code for
.Net and have Mono use libvirt.so.0 on Linux and libvirt.dylib on OSX.
This result in a platform independent binary regarding this issue.
[1]
http://www.mono-project.com/Config_DllMap
I'm currently trying to remove strdup call by Custom Marshaling
but it seems
that .Net (or Mono anyway) doesn't allow to use custom marshaler with
structure (and we need it for virConnectCredential structure). If anyone had
an idea...
Regarding this issue my friend suggested to stop libvirt from taking
ownership of cred.result. We could do that by making
virConnectOpenAuth take a new VIR_CONNECT_COPY_CRED_RESULT (or
VIR_CONNECT_DONT_FREE_CRED_RESULT or VIR_CONNECT_CONST_CRED_RESULT)
flag that lets libvirt internally strdup() cred.result before passing
it to the driver. That way the C# bindings could pass a managed string
as cred.result and we don't need to Marshal.StringToHGlobalAuto() and
strdup in C# at all.
Or we could make libvirt take a custom free function to free
cred.result instead of free(). That way Marshal.FreeHGlobal could be
used or no free function at all and you pass a managed string to it.
This would probably require a new version of virConnectOpenAuth and I
consider this as too invasive.
Another possibility would be to add a public virAlloc to libvirt that
C# can use to allocate memory that can be freed using free().
Matthias