日期:2014-05-18  浏览次数:21203 次

C#调用DLL,出现“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”
代码如下:
  [DllImport("wsnmp32.dll")]
  public static extern SNMPAPI_STATUS SnmpStrToOid(StringBuilder str, ref SMIOID oid);
  StringBuilder name2 = new StringBuilder(256);
  name2.Append("1.3.6.1.2.1.2.2.1.16");
  SnmpAPI.SnmpStrToOid(name2, ref Oid);
使用果网上很多方法都不行,SnmpAPI.SnmpStrToOid总会抛出“尝试读取或写入受保护的内存。这通常指示其他内存已损坏”这个异常。请问各位高手怎么解决,谢谢,分数不够可以另开贴加分

------解决方案--------------------
C/C++ code

C++
SNMPAPI_STATUS SnmpStrToOid(
  __in   LPCSTR string,
  __out  smiLPOID dstOID
);

------解决方案--------------------
C# code

 [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct SMIOID
        {
            [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.I4)]
            public uint size;
            public IntPtr dwords;
        }

------解决方案--------------------
注意第一个参数的类型是LPCSTR,而不是LPCTSTR。所以你要用[DllImport("wsnmp32.dll", CharSet=ANSI)](不是确切代码,大概如此)。

还有就是如果不是OUT类型的字符串参数,可以不使用StringBuilder。这里明显可以不用StringBuilder。
------解决方案--------------------
检查字符类型
------解决方案--------------------

用UnmanagedType试试.我之前也碰到过这个问题,将变量声明为UnmanagedType就解决了.
------解决方案--------------------
我看第一个象是C++里面没有符号的32位Long型数据,所以对应的应该是Uint32 没有错,可能是第二个参数需要限定下程度,也是32位,如果还不行我也没办法了:

C# code

        StructLayout(LayoutKind.Sequential)]
        public struct SMIOID
        {
            public Uint32 size;
            [MarshalAs(UnmanagedType.I4, SizeConst=32)]
            public IntPtr dwords;
        }

       //然后调用的指针的函数改成下面的

         [DllImport("wsnmp32.dll")] 
        public static extern SNMPAPI_STATUS SnmpStrToOid(StringBuilder str, out ref SMIOID oid); 
                    StringBuilder name2 = new StringBuilder(256); 
                    name2.Append("1.3.6.1.2.1.2.2.1.16"); 
                    SnmpAPI.SnmpStrToOid(name2, out ref Oid);

------解决方案--------------------
这个问题我也遇到过,最终检查问题出在DLL里面,里面通过指针动态申请的空间没有释放.不知道你是不是跟我一样的.