[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


Try our interop tutorial. It has some answers to your questions.



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