【发布时间】:2017-04-21 09:14:08
【问题描述】:
我目前正在编写一些与 C++ dll 对话的 C# 代码。这不是我 - 或我公司的其他人 - 有任何经验的领域。至少可以说是令人大开眼界。
经过大量阅读、反复试验和挫折后,我设法消除了大部分问题,并获得了大部分功能性的东西。然而,它还是时不时地把这个扔给我……
System.AccessViolationException:试图读取或写入受保护的内存。这通常表明其他内存已损坏。
.. 然后死了。仅当我在并行线程上运行调用时才会出现此错误 - 单线程很好。这个 dll 应该是线程安全的,如果处理得当,我们有充分的理由相信它应该是线程安全的。
这个错误的原因总是对同一个函数的调用:
[DllImport(DLL, SetLastError = true, CharSet = CharSet.Ansi)]
public static extern int QABatchWV_Close(IntPtr vi1);
我有这个库的头文件,它将这个函数定义为:
__declspec(dllimport) int __stdcall QABatchWV_Close(int);
据我了解,我还可以使用其他工具,例如 SafeHandle 和 MarshalAs。但是,坦率地说,我不确定在这种情况下如何最好地部署它们。
这个错误往往需要几个小时的使用时间才会出现,所以在这里调整和希望不会是一种有效的方法。谁能指出我在调用 C++ 函数时可能做错了什么?
【问题讨论】:
-
您决定将参数用作
IntPtr而不是返回值中的int是否有原因? -
@nvoigt 实验,试图让它正常运行。如图所示,我已经尝试过在两端使用 int,在两端使用 IntPtr,并且每个都使用一个。我很高兴承认我对此一无所知,只是在绝望中尝试。
-
您需要了解编译 C++ 库时
int的大小。然后你需要在 C# 中选择正确的东西。IntPtr是 32 位还是 64 位,具体取决于您执行代码的位置。您的 C++ 库无法像 C# 那样在运行时决定,它将在编译时修复。 -
@nvoigt 好的,谢谢,我想我需要回到供应商那里吗?此外,当我编辑问题时,我只会在并行线程上运行应用程序时收到此错误。这永远不会发生单线程。这仍然可能是由 int 大小不同引起的吗?