我有一个非托管DLL,它暴露了一个带有指向数据结构的指针的函数。我有C#代码创建数据结构并调用dll函数没有任何问题。在函数调用dll时,指针是正确的。
我的问题是DLL保留指向结构的指针,并在稍后的时间点使用数据结构指针。当DLL开始使用指针时它变得无效(我假设.net运行时已将内存移到其他地方)。
这个问题的可能解决方案是什么?
我能想到的可能解决方案是:
还有其他更好的解决方案吗?
答案 0 :(得分:2)
您可以使用AllocHGlobal分配结构,将其置于非托管内存中,GC不会移动它或释放它。你也可以使用像this这样的辅助类让GC引脚作为内存,所以在取消固定之前它不会被移动或释放。
答案 1 :(得分:1)
答案 2 :(得分:1)
非常接近。
在这个特定的情况下,我P / Invoke LocalAlloc分配内存块并使用StructureToPtr来初始化它。
更新:由于您可以编辑DLL,我会更改DLL以提供AllocXXX和FreeXXX功能。
答案 3 :(得分:0)
如果没有手头的DLL试试这个,很难说这是否有用。我会尝试在C#类中使对象“固定”,这样内存就会在应用程序的生命周期中挂起。然后只需将静态对象传递给DLL。
答案 4 :(得分:0)
GCHandle类旨在处理这种确切的情况。基本上,您将结构的副本装入堆中,然后使用GCHandle.Alloc
调用GCHandleType.Pinned
。当DLL完成结构时,请调用GCHandle.Free
。要为DLL函数提供对象的地址,请将其传递给GCHandle.AddrOfPinnedObject
。只要它被固定,GC就不会移动它。