C# 从回调调用非托管代码时,应如何返回委托?
我遇到了这样一种情况:我正在进出un/托管代码,我认为我的方法使我得到了一个“FatalExecutionEngineError”。具体来说,我有一个C回调(“x”),它将另一个回调(“y”)返回到C,其中X和Y都是用非托管C++代码调用的(C调用)。从回调Y返回时引发错误C# 从回调调用非托管代码时,应如何返回委托?,c#,c++,delegates,unmanaged,dllimport,C#,C++,Delegates,Unmanaged,Dllimport,我遇到了这样一种情况:我正在进出un/托管代码,我认为我的方法使我得到了一个“FatalExecutionEngineError”。具体来说,我有一个C回调(“x”),它将另一个回调(“y”)返回到C,其中X和Y都是用非托管C++代码调用的(C调用)。从回调Y返回时引发错误 Dll导入语句: [DllImport ("SearchDLL.dll", CallingConvention = CallingConvention.Cdecl)] public static extern unsafe
Dll导入语句:
[DllImport ("SearchDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern unsafe bool Dll_Search_Text (..., delegate_add_result Fn);
非托管C代码:
extern "C" {
__declspec(dllexport) bool Dll_Search_Text (..., bool (*Add_Result (int, int)) (int, int, int)) {
bool (*Add_Result_Word) (int, int, int);
bool Add_Word_Ret;
...
Add_Result_Word = Add_Result ([int param], [int param]);
if (0 == Add_Result_Word) return false;
...
for (Itr=Set->begin (); Itr != Set->end (); Itr++) {
...
Add_Word_Ret = Add_Result_Word ([int param], [int param], [int param]);
}
}
return true;
}
}
代表定义:
public delegate bool delegate_add_result_word (int A, int B, int C);
public delegate delegate_add_result_word delegate_add_result (int D, int E);
错误消息:
"Managed Debugging Assistant 'FatalExecutionEngineError' has detected a
problem in 'C:\Neuric\bin\Search.exe'. Additional Information: The
runtime has encountered a fatal error. The address of the error was
at 0x6ea2ceca, on thread 0x744. The error code is 0xc0000005. This
error may be a bug in the CLR or in the unsafe or non-verifiable
portions of user code. Common sources of this bug include user marshaling
errors for COM-interop or PInvoke, which may corrupt the stack."
代码在某些时候可以工作(在我添加嵌套回调之前工作得很好),但在其余时间会抛出此异常。代理通常使用fastcall。但是c风格的函数指针使用cdecl。使用unamangedFunctionPointer属性标记您的代理。代理通常使用fastcall。但是c风格的函数指针使用cdecl。用unamangedFunctionPointer属性标记您的代理。我不确定您到底在做什么,但我可以想到两个原因。我假设您已将委托转换为函数指针。然后
- 必须确保委托对象未被垃圾收集。GC没有看到您的函数指针,因此它会立即清理委托。命名空间msclr中有几个句柄容器,但是如果您正在处理复杂的场景,则可能需要手动分配
。当然,您可能已经在这样做了;-)李>GCHandle
- 您必须进一步确保在访问GC受控对象时不会移动对该对象的引用
是在本地实现这一点的一种方法,但听起来像是在以复杂的方式传递东西,因此这可能意味着您需要使用pin_ptr
- 必须确保委托对象未被垃圾收集。GC没有看到您的函数指针,因此它会立即清理委托。命名空间msclr中有几个句柄容器,但是如果您正在处理复杂的场景,则可能需要手动分配
。当然,您可能已经在这样做了;-)李>GCHandle
- 您必须进一步确保在访问GC受控对象时不会移动对该对象的引用
是在本地实现这一点的一种方法,但听起来像是在以复杂的方式传递东西,因此这可能意味着您需要使用pin_ptr
- 我不确定你到底在做什么,但我能想到两个原因。我假设您已将委托转换为函数指针。然后