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&lt;MonoString*&gt;(answer)) works like a charm and leaks nothing.<br><br><div><span class="gmail_quote">
On 8/25/07, <b class="gmail_sendername">Zoltan Varga</b> &lt;<a href="mailto:vargaz@gmail.com">vargaz@gmail.com</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi,<br><br>Try our interop tutorial. It has some answers to your questions.<br><br><a href="http://www.mono-project.com/Interop_with_Native_Libraries">http://www.mono-project.com/Interop_with_Native_Libraries</a><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Zoltan
<br><br>On 8/25/07, Sebastian Good &lt;<a href="mailto:sebastian@palladiumconsulting.com">sebastian@palladiumconsulting.com</a>&gt; wrote:<br>&gt;&nbsp;&nbsp;Thanks to help on this list I&#39;ve come a long way in embedding mono into my
<br>&gt; C++ application. During the transition of a very large application (25+ yrs<br>&gt; of C, Fortran, &amp; C++) towards managed code, we will be adding new code in<br>&gt; .NET languages, but needing to access these objects from C++ fairly
<br>&gt; intimately. Therefore I&#39;m looking at writing wrappers which expose CLR<br>&gt; classes as C++ classes -- without resorting to (XP)COM or CORBA. I figure<br>&gt; most of these can be auto-generated. I believe it will make sense to emit
<br>&gt; mono-embedding wrappers for Linux and Managed C++ wrappers for Windows. If<br>&gt; anyone else is interested (or has already undertaken!) such an effort, let<br>&gt; me know. However I&#39;m still looking at some marshalling issues.
<br>&gt;<br>&gt;&nbsp;&nbsp;If I call .NET functions exclusively via the embedding reflection API, e.g.<br>&gt; mono_runtime_invoke, and carefully call g_free on returned copies of things<br>&gt; like strings, everything works fine, including managed exceptions. It seems
<br>&gt; that&nbsp;&nbsp;by caching the reflected objects, e.g. MonoMethod*, performance is<br>&gt; good.<br>&gt;<br>&gt;&nbsp;&nbsp;However I am having problems with delegates invoked across the barrier.<br>&gt; They execute properly, but appear to leak memory, and I am not sure how to
<br>&gt; catch exceptions they might throw. For the majority of our interop, we can<br>&gt; avoid attempting this scenario, but we&#39;d like to investigate it so that we<br>&gt; can provide managed callbacks for unmanaged code to call.
<br>&gt;<br>&gt;&nbsp;&nbsp;In our C++, we define (using MSVC syntax for this prototype)<br>&gt;<br>&gt; // function: string-&gt;string<br>&gt;&nbsp;&nbsp;typedef char* (__stdcall * action_string)(char*);<br>&gt;<br>&gt;&nbsp;&nbsp;// managed code will stash a delegate here for use by unmanaged code
<br>&gt;&nbsp;&nbsp;action_string _f_string;<br>&gt;&nbsp;&nbsp;extern &quot;C&quot; _declspec(dllexport) void __stdcall init_string(action_string f)<br>&gt;&nbsp;&nbsp;{&nbsp;&nbsp;_f_string =f ; }<br>&gt;<br>&gt;&nbsp;&nbsp;// the unmanged code actually calls this code, 
e.g. do_string(&quot;hello&quot;)<br>&gt;&nbsp;&nbsp;extern &quot;C&quot; _declspec(dllexport) char* __stdcall do_string(char* s);<br>&gt;&nbsp;&nbsp;{&nbsp;&nbsp;return _f_string(s); }<br>&gt;&nbsp;&nbsp;then in C# we write<br>&gt;<br>&gt; // function: string-&gt;string, equivalent to action_string above
<br>&gt;&nbsp;&nbsp;public delegate string ActionString(string _);<br>&gt;<br>&gt;&nbsp;&nbsp;// the managed code we&#39;ll be calling from unmanaged code<br>&gt;&nbsp;&nbsp;public static string Echo(string s) { return s+s; }<br>&gt;<br>&gt;&nbsp;&nbsp;// and the bootstrapper
<br>&gt;&nbsp;&nbsp;[DllImport(&quot;libhost&quot;)] public static extern void init_string(ActionString<br>&gt; s);<br>&gt;&nbsp;&nbsp;public static void Boot { init_string(Echo); }<br>&gt;&nbsp;&nbsp;and again in C++, we can actually call the managed code like so
<br>&gt;<br>&gt; // find_method is just a shortcut using debug-helpers<br>&gt;&nbsp;&nbsp;MonoMethod *bootMethod = find_method(&quot;Hello.World:Boot&quot;, image);<br>&gt;&nbsp;&nbsp; mono_runtime_invoke(bootMethod, NULL, NULL, NULL);<br>&gt;&nbsp;&nbsp;// now we have a function pointer we can call
<br>&gt;&nbsp;&nbsp;char *result = do_string(&quot;hello&quot;);<br>&gt;&nbsp;&nbsp;g_free(result);<br>&gt;&nbsp;&nbsp;Everything works. However, there appears to be a memory leak. I am not sure<br>&gt; whether it is the input that is leaking (i.e. a copy of&nbsp;&nbsp;char*&quot;hello&quot; turned
<br>&gt; into utf16&quot;hello&quot;), or if I am improperly freeing the output (which I must<br>&gt; assume is a copied string) or something else in the internals. What is<br>&gt; encouraging is that all the marshalling is correct, just leaky. Also, if the
<br>&gt; managed code throws an exception, the program prints an error message<br>&gt; (&quot;uncaught exception&quot;) and hangs. I am not sure what I would have expected<br>&gt; on the C++ side, perhaps a C++ exception, perhaps silence.
<br>&gt;<br>&gt;&nbsp;&nbsp;&gt;From the fact that the function pointers work at all, I can tell a lot of<br>&gt; thought has already gone into this PInvoke stuff. What am I missing on the<br>&gt; garbage collection side? (And as soon as the strings work, I need to worry
<br>&gt; about making sure that managed delegate doesn&#39;t move or get garbage<br>&gt; collected!)<br>&gt;<br>&gt;&nbsp;&nbsp;Thanks<br>&gt;<br>&gt;&nbsp;&nbsp;Sebastian<br>&gt; _______________________________________________<br>&gt; Mono-devel-list mailing list
<br>&gt; <a href="mailto:Mono-devel-list@lists.ximian.com">Mono-devel-list@lists.ximian.com</a><br>&gt; <a href="http://lists.ximian.com/mailman/listinfo/mono-devel-list">http://lists.ximian.com/mailman/listinfo/mono-devel-list
</a><br>&gt;<br>&gt;<br><br></blockquote></div><br>