Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a native callback from managed .NET code (when loading the managed code using COM)

I am really confused by the multitude of misinformation about native / managed interop.

I have a regular C++ exe which is NOT built using CLR stuff (it is neither Managed C++ nor C++/CLI and never will be). This C++ exe is "in charge", there is no managed wrapper for it.

I would like to access some code I have in a C# assembly from my C++ exe. I can access the C# assembly from my C++ code using COM. However, when my C# code detects an event I would like it to call back into my C++ code. The C++ function pointer to call back into will be provided at runtime. Note that the C++ function pointer is to a function found in the exe's execution environment. It may use static members from there. I don't want the managed code to try and load up some DLL to call a function (there is no DLL).

How do I pass this C++ function pointer to my C# code through COM/.NET and have my C# code successfully call it?

Thanks!

like image 376
evilfred Avatar asked May 27 '10 22:05

evilfred


2 Answers

You'll probably want to use Marshal.GetDelegateForFunctionPointer:

  1. Create a delegate type that matches the signature of the native function, keeping in mind the right way to marshal types and using MarshalAs as needed
  2. Communicate the native function pointer from your native code to your C# code however you can (in your case, it looks like you can use your COM -> C# connection)
  3. Use Marshal.GetDelegateForFunctionPointer to turn the pointer into a C#-callable delegate
  4. Invoke the delegate with your parameters

Junfeng Zhang has an example of doing this here.

Note the restrictions mentioned on MSDN:

The GetDelegateForFunctionPointer method has the following restrictions:

  • Generics are not supported in interop scenarios.
  • You cannot pass an invalid function pointer to this method.
  • You can use this method only for pure unmanaged function pointers.
  • You cannot use this method with function pointers obtained through C++ or from the GetFunctionPointer method.
  • You cannot use this method to create a delegate from a function pointer to another managed delegate.

The part about C++ is likely referring to function pointers for class methods. This should still work for global functions.

like image 103
Chris Schmich Avatar answered Nov 09 '22 07:11

Chris Schmich


The standard COM approach is to subscribe to an event that's raised by the COM server. Use can use the event keyword in C#, CLR interop automatically implements the COM glue that's needed. Use the IConnectionPoint interface in your C++ code. Backgrounder is here.

like image 31
Hans Passant Avatar answered Nov 09 '22 07:11

Hans Passant