c++ - 将托管函数指针作为非托管回调传递

标签 c++ .net winapi c++-cli unmanaged

我正在尝试将托管函数指针 void (*)(void *) 传递到我的非托管库。我的非托管库使用指向受 CriticalSection 保护的数据帧的指针调用此回调。当托管回调运行时,由于关键部分,没有其他任何东西可以修改数据帧。但是,我仅通过输入回调就遇到了访问冲突和堆损坏。

编辑:我忘了说了。 StartStreaming() 窃取了它管理的线程。此外,它还创建了一个单独的线程,用于将新数据分派(dispatch)给给定的回调。在这个单独的线程中调用回调。

到目前为止,我已经完成了以下操作:

//Start Streaming
streaming_thread_ = gcnew Thread(gcnew ThreadStart(&Form1::WorkerThreadFunc));
streaming_thread_->Start();

地点:

extern "C" {
#include "libavcodec\avcodec.h"
#include "libavutil\avutil.h"
}

namespace TEST_OCU {

delegate void myCallbackDelegate(void * usr_data); //Declare a delegate for my unmanaged code

public ref class Form1 : public System::Windows::Forms::Form
{
    public:

    static void WorkerThreadFunc()
    {
        myCallbackDelegate^ del = gcnew myCallbackDelegate(&Form1::frame_callback);

        MessageBox::Show("Starting to Streaming", "Streaming Info");
        if(rtsp_connection_ != NULL)
            rtsp_connection_->StartStreaming();
            //rtsp_connection_->StartStreaming((void (*)(void *)) System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(del).ToPointer() );
        MessageBox::Show("Done Streaming", "Streaming Info");
    }

    static void __cdecl frame_callback(void * frame)
    {
        AVFrame * casted_frame = (AVFrame *)frame;
    }

private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) 
    {
        if(rtsp_connection_ == NULL)
            rtsp_connection_ = new NeyaSystems::RTSPConnection("rtsp://url");
    }

    private: static RTSPConnection * rtsp_connection_ = NULL;
}
}
  • 我省略了很多无意义的代码...
  • StartStreaming 默认为 NULL 指针,在这种情况下我不会损坏
  • StartStreaming 使用委托(delegate)函数指针导致堆损坏
  • RTSPConnection 在 native C++ 中实现并包含 C 调用(libavcodec)
  • RTSPConnection 包含两个线程,通信和帧调度线程(调用托管回调)

谁能给我一个面包屑?非常感谢您。

最佳答案

编辑:跨线程调用不是问题。如果非托管调用方希望调用 __cdecl 函数,则必须使用 UnmanagedFunctionPointerAttribute 属性修饰委托(delegate)类型。

using namespace System::Runtime::InteropServices;

[UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)] 
delegate void myCallbackDelegate(void * usr_data); 

关于c++ - 将托管函数指针作为非托管回调传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11298225/

相关文章:

C++ 多模板纯虚继承

c# - 使用 XmlDocument 遍历 XML

.net - 在 .NET DataTable 中存储数据的内存开销是多少?

winapi - 在 Windows 上的自定义控件中处理任意文本输入的正确现代方法是什么? WM_CHAR? IMM? TSF?

c++ - 在 Windows 10 上检测事件的虚拟桌面 - 任务 View - 虚拟桌面切换器

c++ - 我将使用哪个 HWND 在 WinMain 函数中创建对话框?

c++ - C++ 编程语言练习第 3 版 - 桌面计算器

c++ - 让 clang-tidy 修复头文件

c++ - C++ 中的嵌入式资源

.net - Xamarin Android 辅助服务泄漏内存