如何将委托或函数指针从C#传递给C ++并使用InternalCall在那里调用它

我在C#中进行了以下设置:

public delegate void CallbackDelegate(string message); [MethodImplAttribute(MethodImplOptions.InternalCall)] public static extern void setCallback(CallbackDelegate aCallback); public void testCallbacks() { System.Console.Write("Registering C# callback...\n"); setCallback(callback01); } public void callback01(string message) { System.Console.Write("callback 01 called: " + message + "\n"); } 

这在C ++中(该函数通过mono_add_internal_call正确注册):

 typedef void (*CallbackFunction)(const char*); void setCallback(MonoDelegate* delegate) { // How to convert the MonoDelegate to a proper function pointer? // So that I can call it like func("test"); } 

调用C ++函数,并将某些内容传递给委托变量。 但现在呢?

我环顾四周,发现了几次提到的函数“mono_delegate_to_ftnptr”,从这些例子来看,它似乎正是我所需要的。
但是,这个函数似乎在我的mono(4.6)分布中似乎不存在,所以我只能猜测它不再存在。

我还找到了一些如何使用PInvoke执行此操作的示例。 这是我不想使用的东西 – 因为InternalCall对我来说要快得多。
当然,如果PInvoke是唯一的方式,那就这样吧,但我对此表示怀疑。

最后,我真的不知道如何从这里开始。

经过几个小时的挖掘后,我终于找到了一个(?)解决方案。
基本上,对PInvoke方法有效的方法也适用于此,您可以将函数指针而不是C#中的委托传递给C(++)。
我更喜欢一个可以直接传递委托的解决方案,但是你总是可以在C#中添加一些包装代码,至少让它看起来像那样。

解:

C#:

 public delegate void CallbackDelegate(string message); [MethodImplAttribute(MethodImplOptions.InternalCall)] public static extern void setCallback(IntPtr aCallback); private CallbackDelegate del; public void testCallbacks() { System.Console.Write("Registering C# callback...\n"); del = new CallbackDelegate(callback01); setCallback(Marshal.GetFunctionPointerForDelegate(del)); System.Console.Write("Calling passed C++ callback...\n"); } public void callback01(string message) { System.Console.Write("callback 01 called. Message: " + message + "\n"); } 

C ++:

 typedef void (*CallbackFunction)(MonoString*); void setCallback(CallbackFunction delegate) { std::cout << &delegate << std::endl; delegate(mono_string_new(mono_domain_get(), "Test string set in C++")); } 

但请注意:您需要以某种方式将代理保留在C#中(这就是我将其分配给“del”的原因)或者它将被GC捕获并且您的回调将变为无效。
当然,这是有道理的,但我觉得在这种情况下很容易忘记。