我试图将托管函数指针void (*)(void *)
传递给我的非托管库。我的非托管库使用指向由CriticalSection保护的数据框的指针调用此回调。托管回调正在运行时,由于关键部分,其他任何内容都不能修改数据帧。但是,我只是通过输入回调来获得访问违规和堆腐败。将托管函数指针传递为非托管回调
编辑:我忘了提。 StartStreaming()
窃取它管理的线程。此外,它创建一个单独的线程来分派新数据到给定的回调。回调在这个单独的线程中被调用。
到目前为止,我已经做了如下:
//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
与委托ED函数指针导致堆损坏RTSPConnection
在本地C++实现和含有C呼叫以及(libavcodec的)RTSPConnection
包含两个线程,通信和帧调度线程(调用管理回调)
有人给我一个面包屑?提前谢谢你。
嘿梦露,你的意思是WorkerThreadFunc?在我真正的电话中,我在我的frame_callback中有GUI调用,并且我在'Form :: Update()'委托上使用'BeginInvoke'。 – Constantin
@Constantin我通过经验发现,执行BeginInvoke的最佳位置应该在Form实例本身中......它拥有最好的上下文来知道调用线程是否是UI线程。 –
啊,我现在看到你没有在frame_callback中调用任何UI函数;我的错。也许删除__cdecl? –