我想从 C++ 非托管代码调用 C# 委托。无参数委托工作正常,但有参数委托使我的程序崩溃
Posted
技术标签:
【中文标题】我想从 C++ 非托管代码调用 C# 委托。无参数委托工作正常,但有参数委托使我的程序崩溃【英文标题】:I want to call a C# delegate from C++ unmanaged code. A parameterless delegate works fine , but a delegate with parameters crashed my program 【发布时间】:2010-07-30 18:39:39 【问题描述】:以下是来自未管理的 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);
【问题讨论】:
【参考方案1】:函数指针的调用约定错误。让它看起来像这样:
int (__stdcall * pt2Func)(args...)
【讨论】:
【参考方案2】:所以这应该有效:
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);
【讨论】:
以上是关于我想从 C++ 非托管代码调用 C# 委托。无参数委托工作正常,但有参数委托使我的程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章
让非托管 c++ 代码调用调用 c# 代码的托管 c++ 代码
从 C# 如何调用需要 *VARIANT 参数的非托管 OLE 接口?
对“xxx”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。 错误解决一例。(代码片段