[Mono-list] C/C++ code that calls .NET code with Mono?

Jonathan Pryor jonpryor@vt.edu
Sat, 07 Feb 2004 17:32:01 -0500


On Sat, 2004-02-07 at 17:01, Sijmen Mulder wrote:
> Is there a way to let C/C++ code call .NET code? Like, some libraries 
> provide events - how to get those events into a .NET application/library?

Yes.  Use delegates.  Or use COM on Windows... ;-)

Delegates are the preferred mechanism, given that they're portable to
Mono.  Delegates map to a function pointer, and should be usable
transparently from unmanaged code:

	// C code
	typedef void (Callback*)();

	void register_callback (Callback cb);

	// C# code:
	delegate void Callback ();

	class Test {
		[DllImport ("some-library")]
		private static extern void register_callback
			(Callback cb);

		private void MyCB () {/* ... */}

		public static void Main ()
			Test t = new Test ();
			Callback cb = new Callback (t.MyCB);
			register_callback (cb);

I haven't tested the above, but that should be the basic gist of it.

Important: the delegate reference you pass to unmanaged code *must* not
be considered to be garbage by the GC, or else the GC will collect the
delegate, the runtime will free the unmanaged memory that the unmanaged
code is using as a function pointer, and Bad Things Will Happen (TM).

How do you do that?  Making the delegate a member of a class is a start,
and making sure that the class instance hangs around for awhile is also
needed.  The above sample code is inadequate, but it gets the basics

The problem with delegates relates to flow-of-control: they assume that
the C# program is in control, and thus able to register callbacks with
the unmanaged code.  If this isn't the case -- you have a primarily
unmanaged program such as Evolution or Visual Studio .NET -- and you
want to create managed types from unmanaged code, you need a different
solution.  On .NET, using COM is the only way to do this; check MSDN and
the COM Interop documentation.  Mono provides an embedding API to do
largely the same thing.

 - Jon