Hi, The input parameter is converted by the runtime from ut8 to a managed string object, which is handled by the GC, so there should be no leak there. The result is converted from a managed string object to ut8, and the caller should free it using g_free (). So your example code should work without a leak.
Zoltan On 8/25/07, Sebastian Good <[EMAIL PROTECTED]> wrote: > Thanks, I've read (and now-reread!) this fairly carefully, but my case is > about C code calling CLI code, not the other way around, so I do not see > explicit instructions about things like, for instance, how to treat the > char* returned from the managed delegate. I would have expected the copy of > the char* I pass to the CLI ("hello", below) to be magically handled by the > CLI, but the document doesn't make 100% clear how to free the char* copy > that comes back from the managed delegate. It seems clear to me that the CLI > can't collect it for me (its lifetime must be managed by C), but it also > seems that I suffer a memory leak even if I try to g_free it. The equivalent > explicit marshaling > (mono_string_to_utf8(reinterpret_cast<MonoString*>(answer)) > works like a charm and leaks nothing. > > > On 8/25/07, Zoltan Varga <[EMAIL PROTECTED]> wrote: > > Hi, > > > > Try our interop tutorial. It has some answers to your questions. > > > > http://www.mono-project.com/Interop_with_Native_Libraries > > > > Zoltan > > > > On 8/25/07, Sebastian Good > <[EMAIL PROTECTED]> wrote: > > > Thanks to help on this list I've come a long way in embedding mono into > my > > > C++ application. During the transition of a very large application (25+ > yrs > > > of C, Fortran, & C++) towards managed code, we will be adding new code > in > > > .NET languages, but needing to access these objects from C++ fairly > > > intimately. Therefore I'm looking at writing wrappers which expose CLR > > > classes as C++ classes -- without resorting to (XP)COM or CORBA. I > figure > > > most of these can be auto-generated. I believe it will make sense to > emit > > > mono-embedding wrappers for Linux and Managed C++ wrappers for Windows. > If > > > anyone else is interested (or has already undertaken!) such an effort, > let > > > me know. However I'm still looking at some marshalling issues. > > > > > > If I call .NET functions exclusively via the embedding reflection API, > e.g. > > > mono_runtime_invoke, and carefully call g_free on returned copies of > things > > > like strings, everything works fine, including managed exceptions. It > seems > > > that by caching the reflected objects, e.g. MonoMethod*, performance is > > > good. > > > > > > However I am having problems with delegates invoked across the barrier. > > > They execute properly, but appear to leak memory, and I am not sure how > to > > > catch exceptions they might throw. For the majority of our interop, we > can > > > avoid attempting this scenario, but we'd like to investigate it so that > we > > > can provide managed callbacks for unmanaged code to call. > > > > > > In our C++, we define (using MSVC syntax for this prototype) > > > > > > // function: string->string > > > typedef char* (__stdcall * action_string)(char*); > > > > > > // managed code will stash a delegate here for use by unmanaged code > > > action_string _f_string; > > > extern "C" _declspec(dllexport) void __stdcall > init_string(action_string f) > > > { _f_string =f ; } > > > > > > // the unmanged code actually calls this code, e.g. do_string("hello") > > > extern "C" _declspec(dllexport) char* __stdcall do_string(char* s); > > > { return _f_string(s); } > > > then in C# we write > > > > > > // function: string->string, equivalent to action_string above > > > public delegate string ActionString(string _); > > > > > > // the managed code we'll be calling from unmanaged code > > > public static string Echo(string s) { return s+s; } > > > > > > // and the bootstrapper > > > [DllImport("libhost")] public static extern void > init_string(ActionString > > > s); > > > public static void Boot { init_string(Echo); } > > > and again in C++, we can actually call the managed code like so > > > > > > // find_method is just a shortcut using debug-helpers > > > MonoMethod *bootMethod = find_method("Hello.World:Boot", image); > > > mono_runtime_invoke(bootMethod, NULL, NULL, NULL); > > > // now we have a function pointer we can call > > > char *result = do_string("hello"); > > > g_free(result); > > > Everything works. However, there appears to be a memory leak. I am not > sure > > > whether it is the input that is leaking (i.e. a copy of char*"hello" > turned > > > into utf16"hello"), or if I am improperly freeing the output (which I > must > > > assume is a copied string) or something else in the internals. What is > > > encouraging is that all the marshalling is correct, just leaky. Also, if > the > > > managed code throws an exception, the program prints an error message > > > ("uncaught exception") and hangs. I am not sure what I would have > expected > > > on the C++ side, perhaps a C++ exception, perhaps silence. > > > > > > >From the fact that the function pointers work at all, I can tell a lot > of > > > thought has already gone into this PInvoke stuff. What am I missing on > the > > > garbage collection side? (And as soon as the strings work, I need to > worry > > > about making sure that managed delegate doesn't move or get garbage > > > collected!) > > > > > > Thanks > > > > > > Sebastian > > > _______________________________________________ > > > Mono-devel-list mailing list > > > Mono-devel-list@lists.ximian.com > > > > http://lists.ximian.com/mailman/listinfo/mono-devel-list > > > > > > > > > > > > _______________________________________________ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list