(in-text)

Jonathan Pryor wrote:

Converting from char* to string seems to work great, could you elaborate on the memory issues that it might create?



That's because Mono, last I knew, was slightly buggy -- it doesn't properly free the memory. .NET does.

The deal is that class types such as System.String (as opposed to
structure types) are always heap allocated. As such, to prevent memory
leaks when a class type is used as the return type of a function, two
things are done:


1: the data is marshaled from unmanaged to managed memory ("marshaled" == "copied, with some potential data transformation applied", such as converting Ansi strings to Unicode strings).

 2: the unmanaged memory is freed.

The problem is (2).  What memory manager is used?  If one memory manager
allocates memory and another memory manager frees it, the heap could
become corrupted.  This is bad.

.NET uses CoTaskMemAlloc() and CoTaskMemFree() as the memory manager
which crosses the managed/unmanaged boundary. Mono will likely use
g_malloc() and g_free(), but last I knew memory wasn't actually being
freed. This is probably why you're not seeing memory corruption. Instead, you'd be seeing memory leaks.


Again, see http://www.jprl.com/~jon/interop.html for more information.



Ah, I see. Thanks for the explanation.

(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*... ;-)



Unfortunately, no. std::string::c_str() converts to a "const char*". Notice the "const"? Furthermore, the memory returned by
std::string::c_str() is managed by the std::string instance. So if you
attempted to manually free this memory (such as when the runtime
marshals the returned string...), you'd get *at best* a double delete,
and *at worst* heap corruption.


Furthermore, if you do something like this:

        const char*
        get_my_string()
        {
                std::string s ("this is my string");
                return s.c_str();
        }

You're *asking* for trouble, as the std::string destructor will free the
memory used to hold the string, so the string returned by
get_my_string() will be pointing to invalid memory.


And guess what, that's actually what I'm doing (basically) - so far, it works, I haven't detected any memory leaks (haven't checked very thoroughly, though).
But you say using marshalling and IntPtr's is the best way to do it?




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.



So don't. :-)

Debug the unmanaged library in an unmanaged test application, and make
sure the unmanaged part *actually works*.  Once that works, *then*
introduce managed code.  To do otherwise is to greatly complicate your
life, as you won't know where the problem is occurring.

I would also suggest using valgrind, to help find memory leaks and
memory corruption in your unmanaged code.

- Jon


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



Probably a good idea. ^_^

Yours,
Simon

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

Reply via email to