(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 - [EMAIL PROTECTED] http://lists.ximian.com/mailman/listinfo/mono-list





_______________________________________________ Mono-list maillist - [EMAIL PROTECTED] http://lists.ximian.com/mailman/listinfo/mono-list

Reply via email to