[Mono-list] InteropServices: DllNotFoundException...?
Simon Ask Ulsnes
simon@ulsnes.dk
Sun, 23 May 2004 13:03:27 +0200
(sorry for top-posting, but)
Thanks for your reply!
As it turned out, I was calling a non-existant function in the GPGME API
that was referenced in the GPGME Info-pages, but was called something
else in gpgme.h.
Converting from char* to string seems to work great, could you elaborate
on the memory issues that it might create?
Also, Mono apparently can't convert from the C++ STL string to .NET
System.String - probably because Mono is written in C...
(I ended up using C++ simply because of the brilliant stream model,
which makes handling of strings (with stringstream) so much more
intuitive and easy).
Luckily, string.c_str() converts from string to char*... ;-)
But yes, I hope this is something that will be improved. Currently, it
is extremely cumbersome to debug a C/C++ library through managed
applications.
- Simon
Jonathan Pryor wrote:
>On Thu, 2004-05-20 at 17:47, Simon Ask Ulsnes wrote:
><snip/>
>
>
>>Of course, I'm using InteropServices to interact with a C library. I
>>made a few wrapper functions in the library, and the basic ones (such as
>>checking the library version and such) work well. But after I added the
>>latest (GetKeyNames and GetKeyXML), loading the library starts shouting
>>Exceptions - namely DllNotFoundException. Yes, the library is in place.
>>
>>
>
>So, it worked at one point, but when you wrapped GetKeyNames and
>GetKeyXML, *then* it started to fail? Is this correct?
>
>What's possible is that you're encountering the mix of two issues. The
>first issue is that, IIRC, when DllNotFoundException is thrown it only
>contains the *initial* library that the runtime attempted to load, *not*
>the actual library which couldn't found.
>
>Meaning if libA.so depends on libB.so, libA.so is present but libB.so
>isn't, DllNotFoundException will give the error stating that libA.so
>couldn't be found.
>
>I believe this will be fixed in the next release of Mono.
>
>The second issue is basically the first: one of the dependent libraries
>likely can't be found.
>
>Run "ldd libsector.so", and make sure that *all* dependent libraries can
>be found.
>
>
>
>>I'm think I'm making a mistake in writing the C library part properly,
>>but what exactly is it I'm doing wrong?
>>
>>
>
>I'm not entirely sure why you're seeing DllNotFoundException; see above
>for a possible explanation.
>
>However, there is another issue present: strings. Your DllImport
>declarations specify that System.String is the return type. This will
>cause the runtime to attempt to free the strings returned by those
>functions. IIRC, Mono will use g_free() to free that memory. If those
>strings weren't allocated by g_malloc(), this could lead to heap
>corruption.
>
>Even worse, it's not portable. .NET uses CoTaskMemAlloc() and
>CoTaskMemFree() to handle memory returned in this fashion, which I
>assume GPGME won't be using.
>
>The solution is simple: don't use strings. Use System.IntPtr and use
>System.Runtime.InteropServices.Marshal.PtrToStringAnsi():
>
> [DllImport("libsecstor.so")]
> private static extern IntPtr GetKeyNames();
>
> private static string RealGetKeyNames ()
> {
> IntPtr r = GetKeyNames ();
> string s = Marshal.PtrToStringAnsi (r);
> // Free `r' as appropriate
> }
>
>If the string returned by GetKeyNames() is in UTF-8, you may need
>alternate processing. Seeing how Gtk# does this would be useful.
>
>See http://www.jprl.com/~jon/interop.html for more information.
>
> - Jon
>
>
>_______________________________________________
>Mono-list maillist - Mono-list@lists.ximian.com
>http://lists.ximian.com/mailman/listinfo/mono-list
>
>
>
>