[Mono-dev] managed code wrappers (exceptions & garbage collection across pinvoke barriers)
Zoltan Varga
vargaz at gmail.com
Sat Aug 25 16:01:11 EDT 2007
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 <sebastian at palladiumconsulting.com> 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 at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>
>
More information about the Mono-devel-list
mailing list