通过Marshal调用托管函数(c#).从本地(c++)线程GetFunctionPointerForDelegate
本文关键字:c++ GetFunctionPointerForDelegate 线程 调用 Marshal 函数 通过 | 更新日期: 2023-09-27 18:08:19
我使用Marshal。获取一个指向本机函数的函数指针。然后,我通过常规的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();
实际上可以从非托管线程调用。问题在于,如果您正在调试托管应用程序,则调试器中实际上不会出现回调中的断点,但您的代码仍将被执行。为了让你的断点工作,你需要启用"本机代码调试"(即使你的断点在托管代码中!)通过进入Project -> Properties -> Debug -> 启用本机代码调试