最近在寫點東西,涉及到了CLR C++與Native C++的互相調用的問題,結果...........糾結啊。多線程
交互原型是這樣的:函數
void* avio_alloc_context( unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), int64_t (*seek)(void *opaque, int64_t offset, int whence));
public ref class test { int Writebuffer(void *opaque,libffmpeg::uint8_t* buf, int buf_size){ } main() { test testobj=gcnew test(); libffmpeg::avio_alloc_context(outbuffer, 32768,0,NULL ,NULL,testobj->Writebuffer ,NULL); }
結果報錯,要求建立指向成員的指針。ui
使用了委託,而後使用 Marshal::GetFunctionPointerForDelegate獲取函數指針結果....this
編譯不報錯了,運行時回調卻是有了,可回調函數return後就報錯..........估計是對象回收或者是非法訪問致使。spa
直接構造了靜態函數線程
int static Writebuffer(void *opaque,libffmpeg::uint8_t* buf, int buf_size)
這個能夠正常回調了,運行也不報錯,可我須要的對象在靜態函數中可獲取不到(爲了多線程考慮,不能用全局對象)。指針
因而須要傳入 void *opaque 參數。code
可是這個要傳的是一個託管對象,咋辦呢?使用pin_ptr,嗯,能夠傳進去。對象
呃,新的問題來了,void *怎轉回託管對象呢?好吧,這個我是沒找到合適的辦法,blog
再次失敗.........
找到了gcroot<>這個模版,必須有這個:#include<vcclr.h>
代碼:
public ref class test { gcroot<BinaryWriter^> _writedStream; int static Writebuffer(void *opaque,libffmpeg::uint8_t* buf, int buf_size){ }
好吧,斜體部分報錯,說是託管類中不能使用非託管對象........
再改:
gcroot<BinaryWriter^>* _writedStream;
此次不報錯了。
繼續:
Open( BinaryWriter^ writer) { *_writedStream=writer; }
結果運行時告訴我找不到對象....好吧,還須要初始化:
_writedStream=new gcroot<BinaryWriter ^>; *_writedStream=writer;
此次終於木有問題了............
avio_alloc_context(outbuffer, 32768,0,this->_writedStream ,NULL,this->Write_buffer ,NULL); Write_buffer(void *opaque,libffmpeg::uint8_t* buf, int buf_size){ array<unsigned char>^ mbuf=gcnew array<unsigned char>(buf_size); System::Runtime::InteropServices::Marshal::Copy((IntPtr)buf,mbuf,0,buf_size); gcroot<BinaryWriter ^>* wr=(gcroot<BinaryWriter ^>*) opaque; BinaryWriter ^writeStream= *wr; writeStream->Write(mbuf,0,buf_size); writeStream->Flush(); return 0; }
就倆字:坑爹