我正在使用Marshal.GetFunctionPointerForDelegate来获取指向本机函数的函数指针。然后我通过常规的DllImport机制将此函数指针传递给一些非托管代码。我用它来回调;本机代码调用回托管(C#)代码。只要回调发生在同一个线程上,一切正常。如果我尝试从我通过CreateThread创建的线程调用托管函数,则会失败。
是否可以通过GetFunctionPointerForDelegate返回的函数指针从本机线程回调托管代码?
C#:
//in class definition
[DllImport("SomeDll")]
public static extern void SetCallback(System.IntPtr function);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public void delegate SomeDelgateType();
public SomeDelgateType OnCallback;
//a function to implement the callback
public void Callback()
{
}
//inside a setup function
OnCallback = new SomeDelgateType(Callback);
SetCallback(Marshal.GetFunctionPointerForDelegate(OnCallback);
当我从C ++调用函数指针时会出现问题。如果它在创建SetCallback函数的原始线程上一切正常。如果我使用CreateThread创建一个本机线程,然后尝试通过指针调用该函数,我会得到以下异常:
Unhandled exception at 0x76674598 (KernelBase.dll) in MissionControl.exe: 0xE0434352 (parameters: 0x80070057, 0x00000000, 0x00000000, 0x00000000, 0x73DB0000).
使用以下堆栈跟踪:
KernelBase.dll!_RaiseException@16() Unknown
clr.dll!RaiseTheExceptionInternalOnly(class Object *,int,int) Unknown
clr.dll!IL_Throw(class Object *) Unknown
02bbc34b() Unknown
[Frames below may be incorrect and/or missing]
[External Code]
native_function_on_different_thread();
答案 0 :(得分:2)
事实证明,您实际上可以从非托管线程调用。问题在于,如果您正在调试托管应用程序,回调中的断点实际上不会出现在调试器中,但您的代码仍将被执行。要使断点正常工作,您需要启用“本机代码调试”(即使断点位于托管代码中!),方法是转到项目 - > 属性 - > 调试 - > 启用本机代码调试。