[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
>
>
>  
>