Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a managed function (C#) via Marshal.GetFunctionPointerForDelegate from a native (C++) thread

I'm using Marshal.GetFunctionPointerForDelegate to get a function pointer to a native function. I then pass this function pointer to some unmanaged code via the regular DllImport mechanism. I'm using this for callbacks; the native code calls back into the managed (C#) code. Everything works fine as long as the callback happens on the same thread. If I attempt to call the managed function from a thread I created via CreateThread it fails.

Is it possible to call back into managed code from a native thread simply via the function pointer that GetFunctionPointerForDelegate returns?

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);

The problem occurs when I call the function pointer from C++. If it's on the original thread that made the SetCallback function everything works. If I create a native thread with CreateThread and then try to call the function via the pointer, I get the following exception:

    Unhandled exception at 0x76674598 (KernelBase.dll) in      MissionControl.exe: 0xE0434352 (parameters: 0x80070057, 0x00000000, 0x00000000, 0x00000000, 0x73DB0000).

With the following stack trace:

        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();
like image 822
Jeffrey Quesnelle Avatar asked Dec 14 '25 17:12

Jeffrey Quesnelle


1 Answers

Turns out that you can actually call from an unmanaged thread. The catch is that if you're debugging your managed application, no break points inside the callback will actually ht in the debugger, but your code will still be executed. To get your breakpoints to work, you'll need to enable "native code debugging" (even though your breakpoint is in managed code!) by going to Project -> Properties -> Debug -> Enable native code debugging.

like image 96
Jeffrey Quesnelle Avatar answered Dec 16 '25 05:12

Jeffrey Quesnelle



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!