抛出AccessViolationException

时间:2010-01-21 00:37:36

标签: c#

我正在开发一个用C#编写的项目,并使用C ++ dll与机器人进行通信。最初该软件是用C#VS 2003编写的,并使用.Net 2.0转换为VS 2008(无需更改代码)。现在,我开始在某些计算机上看到“试图读取或写入受保护的内存......”。当代码从dll调用特定方法时,总是抛出Access违规错误,但是,在整个任务中反复调用相同的方法并执行正常,有时它会抛出错误。此外,机器人似乎执行命令fine,它告诉我传递给dll的值存在,因此可以访问。

带有.Net 1.1的软件已使用多年,并且工作正常,没有丢失任何内存错误。现在它一直在使用.Net 2.0,它只会在某些计算机上抛出错误。

我不确定是什么导致了这个问题。我排除了dll方法的不恰当的调用(不正确的编组...),因为它已经与.Net 1.1一起工作多年,因此在.Net 2.0中也应该可以正常工作。我已经看到一些帖子暗示它可能是GC,但是又一次为什么它只会发生在这台计算机上而且有时只会发生。此外,传入的值是C#代码中的所有全局变量,因此它们应该存在,直到应用程序关闭并且GC没有业务移动任何这些或删除它们。另一个观察,如上所述,机器人正常执行命令,这意味着它获得了所有必要的值。不确定C ++ dll的方法在GC可能搞乱内容的最后会做什么。它不应该尝试删除传入的全局变量,并且方法也没有修改那些变量(我不期望通过传入的值返回任何值,唯一的返回值是方法返回,它也不应该有与GC有关。)

我应该添加的一条重要信息是我无法访问C ++代码,因此无法进行任何更改。

修复必须通过C#代码或计算机上的某些设置或我控制的其他内容。 任何帮助非常感谢。 感谢。

代码段: VS 2003中的原始方法调用

[DllImport("TOOLB32.dll",EntryPoint="TbxMoveWash")]
public static extern int TbxMoveWash(int tArmId, string lpszCarrierRackId, 
                                int eZSelect,  int[] lpTipSet, int tVol, bool bFastW);

我在看到以下错误后修改了(但错误仍然发生):

[DllImport("TOOLB32.dll",EntryPoint="TbxMoveWash")]
public static extern int TbxMoveWash(int tArmId, string lpszCarrierRackId, 
                                int eZSelect, [MarshalAs(UnmanagedType.LPArray, SizeConst = 8)] int[] lpTipSet, int tVol, bool bFastW);

1 个答案:

答案 0 :(得分:0)

C ++ DLL实际上可能会引发访问冲突,因此问题根本不在.NET中。你能在发生异常时停止,捕获输入并尝试从非托管代码中重现问题吗?

如果你确定它在编组中:int是非常安全的,所以有两个嫌疑人 - 字符串和数组参数。如果您不希望收到任何数据,我会标记具有[In]属性的那些数据,因此.NET甚至不会尝试编组数据。然后SizeConst变得无关紧要。

如果没有解决问题,请尝试为字符串指定[MarshalAs],一旦您(以某种方式)找出C ++ DLL所期望的字符串类型。此外,它是ANSI还是Unicode?您可能需要在CharSet中指定[DllImport]

这也可能是.NET CLR中的一个错误(在2.0版中引入)。禁用优化时是否会出现问题(Debug build)?