我想从C ++非托管代码中调用C#委托。 无参数委托可以正常工作,但是带参数的委托会使我的程序崩溃

以下是来自unmanged dll的函数的代码。 它将函数指针作为参数接收,并简单地返回被调用函数返回的值。

extern __declspec(dllexport) int _stdcall callDelegate(int (*pt2Func)()); extern __declspec(dllexport) int _stdcall callDelegate(int (*pt2Func)()) { int r = pt2Func(); return r; } 

在托管的C#代码中,我使用委托调用上面的umanged函数。

  unsafe public delegate int mydelegate( ); unsafe public int delFunc() { return 12; } mydelegate d = new mydelegate(delFunc); int re = callDelegate(d); [DllImport("cmxConnect.dll")] private unsafe static extern int callDelegate([MarshalAs(UnmanagedType.FunctionPtr)] mydelegate d); 

这一切都很棒!! 但如果我希望我的函数指针/委托接受参数,它会使程序崩溃。 因此,如果我修改代码如下,我的程序崩溃。

修改后的非托管c ++ –

 extern __declspec(dllexport) int _stdcall callDelegate(int (*pt2Func)(int)); extern __declspec(dllexport) int _stdcall callDelegate(int (*pt2Func)(int)) { int r = pt2Func(7); return r; } 

修改后的C#代码 –

 unsafe public delegate int mydelegate( int t); unsafe public int delFunc(int t) { return 12; } mydelegate d = new mydelegate(delFunc); int re = callDelegate(d); 

函数指针的调用约定是错误的。 看起来像这样:

  int (__stdcall * pt2Func)(args...) 

所以这应该工作:

C ++ DLL:

 extern "C" __declspec(dllexport) void __stdcall doWork(int worktodo, int(__stdcall *callbackfunc)(int)); 

C#代码:

 delegate int del (int work); [DllImport(@"mydll")] private static extern void doWork(int worktodo, del callback); int callbackFunc(int arg) {...} ... del d = new del(callbackFunc); doWork(1000, d);