Pass Managed Function Pointer As Unmanaged Callback

后端 未结 2 919
我寻月下人不归
我寻月下人不归 2021-01-13 13:24

I am attempting to pass a managed function pointer void (*)(void *) to my unmanaged library. My unmanaged library calls this callback with a pointer to a frame

相关标签:
2条回答
  • 2021-01-13 13:44
     myCallbackDelegate^ del = gcnew myCallbackDelegate(&Form1::frame_callback);
    

    That declares the delegate as a local variable in your method. Local variables are subject to garbage collection right after the last statement that uses them. You are correctly using Marshal::GetFunctionPointerForDelegate() but that's not sufficient to make the garbage collector understand that the delegate is in use, it cannot track references in native code. So the next garbage collection taking place during or after the StartStreaming() call is going to destroy the delegate. And your callback will bomb.

    It isn't clear exactly when callbacks stop being made. At the very least you need to put GC::KeepAlive(del); after the StartStreaming() call. If callbacks are made after the WorkerThreadFunc() stops running, likely considering the "Start" in the method call, you must keep the delegate object alive longer by, say, storing it as a field in your form class. Possible declared static to keep it alive until program termination.

    0 讨论(0)
  • 2021-01-13 13:54

    EDIT: not a problem with cross-thread calls. If the unmanaged caller expects to call a __cdecl function, then you have to decorate the delegate type with an UnmanagedFunctionPointerAttribute attribute.

    using namespace System::Runtime::InteropServices;
    
    [UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)] 
    delegate void myCallbackDelegate(void * usr_data); 
    
    0 讨论(0)
提交回复
热议问题