I’m working on a project that’s written in C# and uses a C++ dll to communicate with a robot. Originally the software was written in C# VS 2003 and was converted to VS 2008 (no change to the code) using .Net 2.0. Now, I started seeing the “Attempted to read or write protected memory…” on some computers. The Access violation error is always thrown when the code calls a particular method from the dll, however, that very same method is called over and over throughout the task and executes fine, just sometimes it throws the error. Also, the robot seems to execute the command fine which tells me that the values passed into the dll exist and thus are accessible.
The software with the .Net 1.1 has been used for years and worked fine without ever throwing any memory errors. Now that it has been using .Net 2.0 it throws errors on some computers only.
I’m not sure what’s causing the issue. I ruled out inappropriate calling (incorrect marshalling …) of the dll methods as it has been working fine with .Net 1.1 for years and thus should work fine in .Net 2.0 as well. I’ve seen some posts suggesting that it could be the GC, but then again why would it only happen on this one computer and only sometimes. Also, the values passed in are all global variables in the C# code and thus they should exist until the application is shut down and GC has no business moving any of those around or deleting them. Another observation, as I mentioned above, the robot executes the command normally which means that it gets all its necessary values. Not sure what the C++ dll’s method would do at the end where the GC could mess up stuff. It shouldn’t try to delete the global variables passed in and the method is not modifying those variables either (I’m not expecting any return values through the passed in values, the only return value is the method return which again shouldn’t have anything to do with GC.)
One important piece of information I should add is that I have no access to the C++ code and thus cannot make any changes there.
The fix has to come through the C# code or some settings on the computer or something else that I am in control of. Any help greatly appreciated. Thanks.
Code snippet: Original method call in VS 2003
[DllImport("TOOLB32.dll",EntryPo开发者_StackOverflow社区int="TbxMoveWash")]
public static extern int TbxMoveWash(int tArmId, string lpszCarrierRackId,
int eZSelect, int[] lpTipSet, int tVol, bool bFastW);
which I modified after seeing the error to the following (but the error still occurs):
[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);
It's possible that the C++ DLL is actually throwing an access violation, so the problem is not in .NET at all. Can you stop when the exception occurs, capture the input and try to reproduce the problem from unmanaged code?
If you're sure it's in the marshalling: the ints are pretty safe, so there are two suspects - the string and the array parameters. If you don't want to receive any data back I'd mark both of those with the [In]
attribute, so .NET doesn't even try to marshal the data back. The SizeConst
then becomes irrelevant.
If that doesn't fix it try specifying [MarshalAs]
for the string, once you (somehow) find out what kind of string the C++ DLL expects. Also, is it ANSI or Unicode? You may want to specify the CharSet
in the [DllImport]
.
It's also possible that this is a bug in the .NET CLR (that was introduced in version 2.0). Does the problem occur with optimisation disabled (Debug build)?
精彩评论