繁体   English   中英

C#到非托管dll数据结构互操作

[英]C# to unmanaged dll data structures interop

我有一个非托管的DLL,它公开了一个需要指向数据结构的指针的函数。 我有C#代码,可以创建数据结构并调用dll函数,而不会出现任何问题。 在对dll的函数调用时,指针是正确的。

我的问题是DLL保留了指向结构的指针,并在以后的某个时间点使用了数据结构指针。 当DLL开始使用指针时,它已变得无效(我假设.net运行时已将内存移至其他位置)。

该问题有哪些可能的解决方案?

我能想到的可能解决方案是:

  • 固定数据结构的内存位置吗? 我不知道您将如何使用C#或什至可以做到这一点。
  • 手动分配内存,以便我可以控制它,例如使用Marshal.AllocHGlobal
  • 更改DLL功能协定以复制结构数据(这是我目前作为短期更改所做的事情,但是如果我能帮助的话,我根本不想更改dl​​l,因为这不是我的代码开头)。

还有其他更好的解决方案吗?

您可以使用AllocHGlobal分配结构,将其放入非托管内存中,GC不会在其中移动或释放它。 你也可以使用一个辅助类像这样有GC引脚的内存,所以它不会被移动或释放,直到取消固定。

  • 手动分配内存,以便我可以控制它,例如使用Marshal.AllocHGlobal

八九不离十。

在这种情况下,我会P /调用LocalAlloc来分配内存块,并使用StructureToPtr对其进行初始化。

更新:因为您可以编辑DLL,所以我将更改DLL以提供AllocXXX和FreeXXX函数。

如果没有手头的DLL来尝试此操作,很难说这是否可行。 我会尝试将对象“固定”在您的C#类中,这样,内存就可以在您的应用程序生命周期中闲逛。 然后只需将静态对象传递给DLL。

GCHandle类旨在处理这种确切的情况。 从本质上讲,你打你的结构复制到堆上,然后调用GCHandle.AllocGCHandleType.Pinned 当DLL完成结构后,调用GCHandle.Free 要为DLL函数提供对象的地址,请将其传递给GCHandle.AddrOfPinnedObject 只要将其固定,GC就不会移动它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM