总结:C# 尝试读取或写入受保护的内存,这通常指示其他内存已损坏。System.AccessViolationException

1、是否运用到了unsafe模式下的非托管内存,是否有两个线程共同访问一个公共对象的情况

在unsafe模式操作非托管内存的情况下,第一个线程使用完这个对象就把这个对象清空,这时候第二个线程正在使用这个对象,就会因为内存中找不到这个内存区域而报错:“尝试读取或写入受保护的内存。这通常指示其他内存已损坏”。

在C#托管内存中,内存回收一般是有GC自动完成的,如果遇到找不到找不到对象的情况,报错信息是“未将对象引用设置到对象的实例”,而非托管内存的找不到对象报错信息是:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。

因为一个非托管对象的操作方式是指针,当内存中的对象被清理掉时,这段内存地址就拒绝指针随意访问,这事指针如果继续访问这段内存,就会报尝试读取或写入受保护的内存这个错误


2、读取或写入受保护

dll文件应该是C++写的。封装了之后供我的C#程序调用,结果就提示了错误:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。错误类型为:System.AccessViolationException。

跨线程操作引起的?因为我的dll控制的是硬件,应该绑定的是窗体句柄。我操作的时候是在一个事件event中操作的,大家知道event是另开线程的。
 

private delegate void CloseDevDelegate();

    private void CloseDev()  
    {  
        if (this.InvokeRequired)  
        {  
            CloseDevDelegate closeDev = new CloseDevDelegate(CloseDev);  
            this.BeginInvoke(closeDev);  
        }  
        else  
        {  
            Program.DEVICE.CloseDev();  
        }  
    }  

在事件中使用:CloseDev()

在事件中使用:CloseDev()


3、在C#中调用别人的DLL的时候有时候出现 尝试读取或写入受保护的内存 。这通常指示其他内存已损坏。

在传值的时候还是用指针,再在C#中做转换就好了。

[DllImport("APPLISTCC.dll")]  
public static extern string TestFunc1(string param1);  
  
string ret1 = TestFunc1("text");  


改成:
[DllImport("APPLISTCC.dll")]  
public static extern IntPtr TestFunc1(IntPtr par1);  
  
IntPtr ptrIn = Marshal.StringToHGlobalAnsi("text");  
IntPtr ptrRet = TestFunc1(ptrIn);  
string retlust = Marshal.PtrToStringAnsi(ptrRet);  

自己在程序里强制释放COM资源,调用Marshal.ReleaseComObject()方法将不再使用的对象释放掉


4、测试的可执行文件与 Windows 数据执行保护功能兼容

调用dll的程序,在运行时会出现 “尝试读取或写入受保护的内存。这通常指示其他内存已损坏。"
有关更多信息,请参见 /NXCOMPAT(与数据执行保护兼容)。
编译器中加入了对DEP的安全性检查,在编译完后的exe文件中取消NXCOMPAT位可解决该问题
editbin.exe /NXCOMPAT:NO myexe
 


5、调用dll动态链接库的时候,参数类型是非常重要的,如果类型不对,就会出现本文这样的错误

C#中开始是这样的引入DLL的,参数分别是long类型与结构体类型,本身和DLL api里面的类型一样

在C#调用DLL动态链接库方法的时候,传值的时候自然也要做一些改变,引用类型的值要加入“ref”关键字,值类型(如com)则直接传入数字或变量名即可


  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HappyGirl快乐女孩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值