以前没有发生过的访问冲突

发布于 08-19 16:06 字数 985 浏览 8 评论 0原文

我正在 P/调用 Graphviz 如此处所示。当我写那篇博客文章时,代码运行得很好。现在,我正在组合一个使用该代码呈现 Graphviz 图形的 HttpModule,但我在 agmemread 处收到 AccessViolationException

// Native signature
Agraph_t agmemread(char *);

// P/Invoke Signature
[DllImport(LIB_GRAPH)]
private static extern IntPtr agmemread(string data);

// Usage
IntPtr g = agmemread(data);

就像我说的,这之前效果很好。但现在,我无法让我的代码在任何情况下工作。甚至我基于相同代码的旧 Graphviz 应用程序也不再工作了。

我可能改变什么会导致这种情况?我什至还没有下载新版本的 Graphviz 或其他任何东西,所以 DLL 都是一样的。

编辑:我尝试将string更改为StringBuilder,但这产生了相同的结果。然后,我添加了一个 MarshalAs 属性:

static extern IntPtr agmemread([MarshalAs(UnmanagedType.LPWStr)] string data);

这样,我不再收到 AccessViolationException,但 Graphviz 无法正确读取字符串并返回空指针。

I'm P/Invoking out to Graphviz as shown here. When I wrote that blog entry, the code worked just fine. Now, I'm putting together an HttpModule that renders Graphviz graphs using that code, but I get an AccessViolationException at agmemread.

// Native signature
Agraph_t agmemread(char *);

// P/Invoke Signature
[DllImport(LIB_GRAPH)]
private static extern IntPtr agmemread(string data);

// Usage
IntPtr g = agmemread(data);

Like I said, this worked perfectly before. But now, I can't get my code to work in anything. Even my old Graphviz apps based on the same code don't work anymore.

What could I have possibly changed that would cause this? I haven't even downloaded a new version of Graphviz or anything, so the DLLs are all the same.

EDIT: I tried changing string to StringBuilder, but that produced the same result. Then, I added a MarshalAs attribute:

static extern IntPtr agmemread([MarshalAs(UnmanagedType.LPWStr)] string data);

With that, I no longer get an AccessViolationException, but Graphviz fails to read the string correctly and returns a null pointer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

意中人2024-08-26 16:06:11

非托管代码很少需要 C# 的大量帮助才能开始生成访问冲突。您的 P/Invoke 签名没有任何问题,这不可能是原因。

非托管代码中最常见的 AV 来源是堆损坏。 C/C++ 代码没有垃圾收集器,必须显式管理内存。它不仅必须负责释放内存(否则会泄漏),还负责分配正确的大小并确保写入分配的内存的代码不会超出分配的内存块的末尾或写入已经释放的内存。最后一个要求是 C/C++ 代码经常失败的地方。

堆损坏的问题在于它极难诊断。它可能会在相当长一段时间内被忽视。造成的典型损害是内部堆结构被破坏,或者另一个堆分配中的数据被覆盖。这不会导致问题,直到稍后释放堆块或使用覆盖的数据时。生成异常的代码实际上并不对之前造成的损害负责。这会让你在试图找到问题根源时走上错误的道路。

找到真正的麻烦制造者非常困难,你只能通过一些线索来找出可能出了问题的地方。当您拥有 C/C++ 源代码时,这非常困难,但使用调试分配器在调试版本中运行它会有所帮助。当你没有源代码时这是不可能的。

除非您可以从之前的调用中查明使用 API 的问题,否则您将需要供应商或支持小组的帮助才能真正解决此问题。祝你好运。

Unmanaged code rarely needs a lot of help from C# to start generating access violations. There's nothing wrong with your P/Invoke signature, that cannot be the cause.

The most common source of AVs in unmanaged code is heap corruption. C/C++ code doesn't have a garbage collector, memory must be managed explicitly. Not only must it take care of releasing memory (or it will leak), it is also responsible for allocating the correct size and making sure that the code that writes to the allocated memory doesn't write past the end of the allocated memory block or writes into memory that was already freed. That last requirement is where C/C++ code often fails.

The trouble with heap corruption is that it is extremely hard to diagnose. It can go unnoticed for quite a while. The typical damage done is that the internal heap structure is compromised, or the data in another heap allocation is overwritten. That doesn't cause a problem until later, when the heap block is released or the overwritten data is used. The code that generates the exception is not actually responsible for the damage that was done earlier. Which sets you off on the wrong track trying to find the source of the problem.

Finding the real trouble maker is very hard, you'd have only a few breadcrumbs to figure out what might have gone wrong. It is very hard when you have the C/C++ source code, but running it in a debug build with a debug allocator helps. It is impossible when you don't have the source code.

Unless you can pin-point a problem with using the API from earlier calls made, you'll need help from the vendor or support group to really solve this problem. Good luck.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文