0
votes

I'm working on a hobby project where I need to call a managed delegate from unmanaged C++. Due to external constraints I also need to pass the delegate from managed code to unmanaged code at runtime.

Ideally, what I would want to do is to simply call the delegate as I would in C# (by invoking the delegate using the same syntax as a method call), but from unmanaged code. I can't figure out how to do this or even if it is possible.

Is this possible to do and if so, how? Must I use events and raise the events from unmanaged code?

This is what I'd want to do.

On the managed side (this is managed C++)

[SerializableAttribute]
[ComVisibleAttribute(true)]
public delegate void CallbackMethod();

[ComVisibleAttribute (true)]
[InterfaceTypeAttribute(ComInterfaceType::InterfaceIsIUnknown)]
[GuidAttribute("CD305837-98FC-4433-A195-BD50C6C16369")]
public interface class ICallback
{
    void QueueCallback(CallbackMethod^ callBack);
};

And, from an unmanaged class that implements the ICallback interface:

HRESULT CIoComplectionPort::QueueCallback(_CallbackMethod * callBack)
{
    // How is the callBack method invoked here?
}
2

2 Answers

4
votes

Just export a function that accepts a function pointer. The C# code can call it, passing a delegate object. The pinvoke marshaller does the heavy lifting, same thing as Marshal.GetFunctionPointerForDelegate(). Which creates a stub that stores the delegate's Target and Method. The function pointer you'll get points to that stub.

The exact same thing happens when C# code pinvokes, say, EnumWindows().

0
votes

You can do it by using C++\CLI , with C++\CLI you can develop a bridge to communicate the two world , from your native C++ invoke a C++\CLI method that invoke the delegate.