版权声明:本博所有原创文章,欢迎转载但不得作为商业用途,转载请注明出处。 https://blog.csdn.net/qq_16587307/article/details/87872582
托管 C++在调用非托管C++时产生如下异常:
System.AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
这个异常调试过程中还无法用try{}catch{}捕获。
SunfytechAPIClrDll::SunfytechAPIClr::SunfytechAPIClr()
{
mySunfyMCA132API = new SunfytechMCA132API(); //initiate C++ class's instance
// pkSFXDataReport = gcnew SFXDataReport_clr();
// cast our managed method to a delegate
callback_SFXData = gcnew SFXDataReportProcess_wrap(&SunfytechAPIClrDll::SunfytechAPIClr::del_SFXDataReport);
// get a pointer to the delegate
IntPtr cbPtr1 = Marshal::GetFunctionPointerForDelegate(callback_SFXData);
// call the native C++ function with our delegate pointer
mySunfyMCA132API->SetProcFunc_SFXDataReport( static_cast<SFXDataReportProcess>(cbPtr1.ToPointer()));
}
实际原因是上述代码中callback_SFXData如果不作为SunfytechAPIClrDll的static成员,那么由于在托管代码下仅仅将它作为函数指针复制给非托管代码,如果callback_SFXData非static成员,在某个时候会被GC回收,导致非托管代码无法使用这个内存而出错。所以callback_SFXData必须是static,如下所示:
public ref class SunfytechAPIClr
{
public:
delegate void SFXDataReportProcess_wrap(SFXDataReport &sfdatareport);
static SFXDataReportProcess_wrap^ callback_SFXData; // 这里需为static,否则会出现"AccessSystem.AccessViolationException" 错误。这是由于callback_SFXData被gcnew之后,由于当前程序控件没有地方再引用它,会导致被系统收回,而在非托管代码中由用了这个它。
delegate void Rx_SFXDataReport(SFXDataReport_clr^ pkclr);
static event Rx_SFXDataReport^ On_SFXDataReportProcess;
......