
2010/10/19 <arnaud.champion@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