求助,C#调用C++dll时提示:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。

问题描述

C++dll的头文件接口描述如下:#pragmapack(push,1)typedefstructXCtrlStatus{XCtrlStatus(unsignedlongV=0){*reinterpret_cast<unsignedlong*>(this)=V;}unsignedcharERR:1;unsignedcharAUTO:1;unsignedcharRUN:2;unsignedcharDIR:2;unsignedchar:1;unsignedchar:1;unsignedcharCTRL:8;unsignedchar:8;unsignedchar:8;operatorunsignedlong()const{return*reinterpret_cast<constunsignedlong*>(this);}}XCtrlStatus;typedefstructXRWSwitch{XRWSwitch(unsignedshortV=0){*reinterpret_cast<unsignedshort*>(this)=V;}unsignedchar:1;unsignedcharOVERLOAD:1;unsignedchar:5;unsignedcharCOLD:1;unsignedcharSCREW:2;unsignedcharGRIP2:2;unsignedcharGRIP1:2;unsignedcharPUMP2:1;unsignedcharPUMP1:1;operatorunsignedshort()const{return*reinterpret_cast<constunsignedshort*>(this);}}XRWSwitch;typedefstructXRSwitchIn{XRSwitchIn(unsignedshortV=0){*reinterpret_cast<unsignedshort*>(this)=V;};unsignedcharRIN_0:1;unsignedcharRIN_1:1;unsignedcharRIN_2:1;unsignedcharRIN_3:1;unsignedcharRIN_4:1;unsignedcharRIN_5:1;unsignedcharRIN_6:1;unsignedcharRIN_7:1;unsignedcharRIN_8:1;unsignedcharRIN_9:1;unsignedcharRIN_A:1;unsignedcharRIN_B:1;unsignedcharRIN_C:1;unsignedcharRIN_D:1;unsignedcharRIN_E:1;unsignedcharRIN_F:1;operatorunsignedshort()const{return*reinterpret_cast<constunsignedshort*>(this);}}XRSwitchIn;typedefstructXRSwitchOut{XRSwitchOut(unsignedshortV=0){*reinterpret_cast<unsignedshort*>(this)=V;};unsignedcharROUT_0:1;unsignedcharROUT_1:1;unsignedcharROUT_2:1;unsignedcharROUT_3:1;unsignedcharROUT_4:1;unsignedcharROUT_5:1;unsignedcharROUT_6:1;unsignedcharROUT_7:1;unsignedcharROUT_8:1;unsignedcharROUT_9:1;unsignedcharROUT_A:1;unsignedcharROUT_B:1;unsignedcharROUT_C:1;unsignedcharROUT_D:1;unsignedcharROUT_E:1;unsignedcharROUT_F:1;operatorunsignedshort()const{return*reinterpret_cast<constunsignedshort*>(this);}}XRSwitchOut;typedefstructXSampleHead{XCtrlStatusStatus;XRSwitchInwRSwitchIn;XRSwitchOutwRSwitchOut;XRWSwitchwRWSwitch;longnControl;unsignedlongdwTimeBase;unsignedshortwReserved;}XSampleHead,*PXSampleHead;typedefconstXSampleHead*PCXSampleHead;typedefstructXSampleV{XSampleHeadHead;floatfSensor[1];}XSampleV,*PXSampleV;typedefconstXSampleV*PCXSampleV;constintXMAX_SENSOR=6;typedefstructXSampleMax_V{XSampleHeadHead;floatfSensor[XMAX_SENSOR];}XSampleMax_V,*PXSampleMax_V;typedefconstXSampleMax_V*PCXSampleMax_V;#pragmapack(pop)typedefunsignedlongXG_RESULT;//函数返回值typedefunsignedlongXG_HANDLE;//设备句柄constXG_RESULTIDX_OK=2000;//表示成功,其他值表示不成功//回调对象,在后台工作者线程中调用,不是在主线程调用structXTopReceivedSink{virtualvoid__stdcallfun1(constvoid*,unsignedlong)=0;//请实现为空函数virtualvoid__stdcallRTM_Sample_Value(PCXSampleVlpcSample,unsignedlongnSensorCount)=0;//请拷贝走数据,尽量短小virtualvoid__stdcallfun3(constvoid*,unsignedchar)=0;//请实现为空函数virtualunsignedchar__stdcallfun5(constvoid*)=0;//请直接返回0virtualunsignedchar__stdcallfun6(char,unsignedchar)=0;//请返直接回0virtualvoid__stdcallfun7(constvoid*,unsignedlong)=0;//请实现为空函数};//如果是采用以太网的方式,请用指定IP地址,如192.168.0.234constTCHAREthernet[]={_T("[Connect]")_T("Dll=EthernetLow.dll;")_T("Type=Host;")_T("IP=%s;")_T("HostPort=7777;")_T("DevicePort=9999;")};//如果是采用串口的方式,请用指定串口号,如COM1constTCHARSerial[]={_T("[Connect]")_T("Dll=SerialLow.dll;")_T("Type=Host;")_T("Port=%s;")_T("Settings=38400,n,8,1;")_T("Addr=1;")};#ifdefEXPLICIT_LOADtypedefXG_RESULT(__stdcall*PGetXTop)(constwchar_t*lpSettings,XG_HANDLE&hTop);typedefXG_RESULT(__stdcall*PFreeXTop)(XG_HANDLEhTop);typedefXTopReceivedSink*(__stdcall*PSetReceivedSink)(XG_HANDLEhTop,XTopReceivedSink*sink);typedefXG_RESULT(__stdcall*PStartRecord)(XG_HANDLEhTop);typedefXG_RESULT(__stdcall*PStopRecord)(XG_HANDLEhTop);typedefXG_RESULT(__stdcall*PGetIndex)(XG_HANDLEhTop,int*Fm,int*FeH,int*FeL,int*Fp,int*E1,int*E2);typedefXG_RESULT(__stdcall*PGetValue)(XG_HANDLEhTop,float*Fm,float*FeH,float*FeL,float*Fp,float*Fd,float*Ek,float*Ed);#elseextern"C"{//获得对象句柄,请为lpSettings传递格式化后的Ethernet或Serial,成功后hTop返回句柄XG_RESULT__stdcallGetXTop(constwchar_t*lpSettings,XG_HANDLE&hTop);//释放对象句柄,对应GetXTop,释放对象句柄之前,请先将回调对象设为0XG_RESULT__stdcallFreeXTop(XG_HANDLEhTop);//设置回调对象,每次有数据到来,都会调用回调对象的RTM_Sample_Value方法//释放对象句柄之前,请先将回调对象设为空XTopReceivedSink*__stdcallSetReceivedSink(XG_HANDLEhTop,XTopReceivedSink*sink);//开始记录数据,StartRecord和StopRecord之间的数据将用于计算结果XG_RESULT__stdcallStartRecord(XG_HANDLEhTop);//结束记录数据,StartRecord和StopRecord之间的数据将用于计算结果XG_RESULT__stdcallStopRecord(XG_HANDLEhTop);//保留XG_RESULT__stdcallGetIndex(XG_HANDLEhTop,int*Fm,int*FeH,int*FeL,int*Fp,int*E1,int*E2);//用StartRecord和StopRecord之间的数据计算结果,分别是://最大力值,上屈服力值,下屈服力值,规定塑性延伸(0.2)力值,规定塑性延伸率截距,弹性段斜率,弹性段截距,不需要可以传空XG_RESULT__stdcallGetValue(XG_HANDLEhTop,float*Fm,float*FeH,float*FeL,float*Fp,float*Fd,float*Ek,float*Ed);}#pragmacomment(lib,"UTMTop.lib")#endif

我的C#声明如下:[DllImport("\ManufacturerDLL\Xingao\UTMTop.dll",SetLastError=true,CharSet=CharSet.Auto)]publicstaticexternXG_RESULTGetXTop(stringlpSettings,refXG_HANDLEhTop);[DllImport("\ManufacturerDLL\Xingao\UTMTop.dll",SetLastError=true,CharSet=CharSet.Auto)]publicstaticexternXG_RESULTFreeXTop(XG_HANDLEhTop);//设置回调对象,每次有数据到来,都会调用回调对象的RTM_Sample_Value方法[DllImport("\ManufacturerDLL\Xingao\UTMTop.dll",SetLastError=true,CharSet=CharSet.Auto)]publicstaticexternUIntPtrSetReceivedSink(XG_HANDLEhTop,refXTopReceivedSinksink);[StructLayout(LayoutKind.Sequential)]publicclassXTopReceivedSink{publicvoidfun1(IntPtra,uintb){return;}publicdelegatevoidCallbackDelegate(refXSampleMax_VlpcSample,uintnSensorCount);publicCallbackDelegateRTM_Sample_Value;//publicvirtualvoidRTM_Sample_Value(refXSampleVlpcSample,ulongnSensorCount);publicvirtualvoidfun3(IntPtra,byteb){return;}publicvirtualbytefun5(IntPtra){return0;}publicvirtualbytefun6(IntPtra,byteb){return0;}publicvirtualvoidfun7(IntPtra,uintb){return;}}[StructLayout(LayoutKind.Sequential)]publicstructXSampleV{publicXSampleHeadHead;[MarshalAs(UnmanagedType.ByValArray,SizeConst=1)]publicfloat[]fSensor;}[StructLayout(LayoutKind.Sequential)]publicstructXSampleMax_V{publicXSampleHeadHead;[MarshalAs(UnmanagedType.ByValArray,SizeConst=6)]publicfloat[]fSensor;}[StructLayout(LayoutKind.Sequential)]publicstructXSampleHead{XCtrlStatusStatus;XRSwitchInwRSwitchIn;XRSwitchOutwRSwitchOut;XRWSwitchwRWSwitch;intnControl;uintdwTimeBase;ushortwReserved;}[DllImport("\ManufacturerDLL\Xingao\UTMTop.dll",SetLastError=true,CharSet=CharSet.Auto)]publicstaticexternXG_RESULTStartRecord(XG_HANDLEhTop);[DllImport("\ManufacturerDLL\Xingao\UTMTop.dll",SetLastError=true,CharSet=CharSet.Auto)]publicstaticexternXG_RESULTStopRecord(XG_HANDLEhTop);[DllImport("\ManufacturerDLL\Xingao\UTMTop.dll",SetLastError=true,CharSet=CharSet.Auto)]publicstaticexternXG_RESULTGetIndex(XG_HANDLEhTop,refintFm,refintFeH,refintFeL,refintFp,refintE1,refintE2);[DllImport("\ManufacturerDLL\Xingao\UTMTop.dll",SetLastError=true,CharSet=CharSet.Auto)]publicstaticexternXG_RESULTGetValue(XG_HANDLEhTop,reffloatFm,reffloatFeH,reffloatFeL,reffloatFp,reffloatFd,reffloatEk,reffloatEd);///<summary>///dll回调对象///</summary>privateXTopReceivedSinktopReceivedSink;

在C#中初始化没有问题:XG_RESULTi=GetXTop(connect,refhDll);if(hDll!=0){//初始化realDataInitReturnData();//时间计数清0milliCount=0;//回调对象实例化,加载对象中的回调委托topReceivedSink=newXTopReceivedSink();topReceivedSink.RTM_Sample_Value+=newXTopReceivedSink.CallbackDelegate(this.CallBackFunction);//回调对象传入dllSetReceivedSink(hDll,reftopReceivedSink);//通知设备开始记录计算用的采集数据StartRecord(hDll);//读数定时器启动timerReceive.Start();return0;}

已经返回成功,返回成功后应该是C#界面等待timer读取回调返回的数据了,但是没有进入timer事件,就立刻提示“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”请高手帮忙看看是哪里存在问题?是我的C#针对dll的结构声明存在问题么?哪里没有匹配上,求助啊,很着急!!!

解决方案

解决方案二:
修改DllImport中CharSet=CharSet.Unicode,增加CallingConvention=CallingConvention.StdCall再试试看
解决方案三:
“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”这种情况,如果你在调试环境下出现此类提示,点击“继续”即可,可以理解为vs“善意的提醒”。不使用vs承载进程,直接运行release版本,通常就不会发生这样的事情。你也可以在项目设置中的“生成”页,勾上“允许不安全的代码”。
解决方案四:
引用1楼xian_wwq的回复:

修改DllImport中CharSet=CharSet.Unicode,增加CallingConvention=CallingConvention.StdCall再试试看

问题依旧
解决方案五:
引用2楼rocmemory的回复:

“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”这种情况,如果你在调试环境下出现此类提示,点击“继续”即可,可以理解为vs“善意的提醒”。不使用vs承载进程,直接运行release版本,通常就不会发生这样的事情。你也可以在项目设置中的“生成”页,勾上“允许不安全的代码”。

也不行,release下程序直接崩溃了
解决方案六:
C++的dll中XCtrlStatus,XRSwitchIn,XRSwitchOut,XRWSwitch四个结构参见顶楼的C++代码,在C#中我不需要使用这四个结构,但是dll声明必须用到,因为C++中这四个结构本意是整形,然后位移操作,我在C#中将他们直接定义成了整形:usingXCtrlStatus=System.UInt32;usingXRSwitchIn=System.UInt16;usingXRSwitchOut=System.UInt16;usingXRWSwitch=System.UInt16;这对调用dll是否有影响?

时间: 2024-11-30 06:01:58

求助,C#调用C++dll时提示:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。的相关文章

C# 调用C++DLL的问题“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”

问题描述 这是c#代码usingSystem.Runtime.InteropServices;namespaceWinCallDll{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}[DllImport(@"......DebugMyDllC.dll",EntryPoint="Add")]publicstaticexternintSendMessage(inta,intb);priv

C#调用其他语言DLL库,提示尝试读取或写入受保护的内存。这通常指示其他内存已损坏

问题描述 C#调用其他语言DLL库,提示尝试读取或写入受保护的内存.这通常指示其他内存已损坏代码如下==========================================DLL函数int__stdcallActionReceived(constchar*devId,constint*windowId,constchar*cmd,char*data)==========================================C#调用[DllImport(@"Caller.dl

C#调用Haskell时的“尝试读取或写入受保护的内存”问题

最近一直被C#调用Haskell时的"尝试读取或写入受保护的内存"问题所困扰(详见C#调用haskell遭遇Attempted to read or write protected memory,C#调用haskell时的"尝试读取或写入受保护的内存"问题),而且困在其中,越陷超深,无法自拔,差点弃用C#解决我们面临的问题. 问题是这样的,只要在Haskell代码中对字符串进行操作,在C#调用时就会引发异常: An unhandled exception of ty

dll c#-c#调用c++的dll出现尝试读取或写入受保护的内存问题

问题描述 c#调用c++的dll出现尝试读取或写入受保护的内存问题 使用c#调用c++的一个dll.c++的接口函数为: extern "C" __declspec(dllexport)bool __stdcall CreateDetmObject(IDetManager **ppDetManager); 参数IDetManager为一个结构体: struct IDetManager { virtual void __stdcall SetListener(HWND hWnd) = 0

winform-C# Winform项目中, 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。

问题描述 C# Winform项目中, 尝试读取或写入受保护的内存.这通常指示其他内存已损坏. C/C++ 代码,这个是第三方提供的外部方法(调用"华大HD-900身份证阅读器接口函数"):int HD_Read_BaseInfo(char* pBmpData char *pName char *pSex char *pNation char *pBirth char *pAddress char *pCertNo char *pDepartment char *pEffectData

C# 读取HTML的时候出错:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。

问题描述 只要html文件存在着句话<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXhtml1.0Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">,读取就会报错,提示尝试读取或写入受保护的内存.这通常指示其他内存已损坏.去掉这句话就没问题了:用到了HTMLEditorControl控件,高手帮解决下 解决方案 解决方案二:呵呵.用WebBrowser.Docum

C# 调用C++的dll,提示&amp;amp;quot;尝试读取或写入受保护的内存。这通常指示其他内存已损坏&amp;amp;quot;

问题描述 C++:GPSSUPPORT_APIint__stdcallress(unsignedchar*compr,unsignedlongcomprLen,unsignedchar**uncompr,unsignedlong*uncomprLen);C#:publicstaticexternintZlibUncompress(refbyte[]compr,longcomprLen,refbyte[]uncompr,reflonguncomprLen);调用:privatebyte[]Keys

C#调用c写的dll 出现:尝试读取或写入受保护的内存。这通常指示其他内存已损坏

问题描述 求助各位大神!我最近在用C#封装一个C写的dll,在调dll中的方法时,时不时会报"尝试读取或写入受保护的内存.这通常指示其他内存已损坏".出现这样的问题,重启下机器就会好了,不过这也不是解决方案,继续大神帮我看看,如何才能杜绝这个问题.char*__readPeopleInfo_json()这个是C写的dll中的方法定义下面是C#引用及调用的代码[DllImport("HealthyCarder.dll")]publicstaticexternIntPt

c++-C# 调用C++ dll是出现这样的错误“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。

问题描述 C# 调用C++ dll是出现这样的错误"尝试读取或写入受保护的内存.这通常指示其他内存已损坏. 调试时是这样的: SDK上是这样说明的: 我调用这个dll时是这样的: 困扰了很久,希望有大神来看一看,感激不敬 解决方案 C#尝试读取或写入受保护的内存.这通常指示其他内存已损坏.C# 尝试读取或写入受保护的内存 .这通常指示其他内存已损坏.C#尝试读取或写入受保护的内存.这通常指示其他内存已损坏. 解决方案二: 先看是不是你的参数有问题,然后就是数据对不对 解决方案三: 是不是重复调用