Hi Matthias,
in fact, it seems that custom marshaling is not the solution. The reason is
that .net (or Mono) doesn't allow the custom marshaling of a struct member.
There one way that I haven't explore : create a custom marshaler for the
structure and manage struct member in the custom marhsaler via "unsafe"
code.
Arnaud
--------------------------------------------------
From: "Matthias Bolte" <matthias.bolte(a)googlemail.com>
Sent: Tuesday, October 19, 2010 6:38 PM
To: <arnaud.champion(a)devatom.fr>
Cc: <libvir-list(a)redhat.com>
Subject: Re: [libvirt] [PATCH] Change/create solution and project for Visual
Studio and MonoDevelop for C# bindings
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