我有一个用C ++设计的DLL,包含在C#项目中,我发现了奇怪的AccessViolationExceptions。我怀疑我的垃圾没有正确收集。我有一个非托管方法apiGetSettings(来自DLL),它应该将数据复制到一个Settings对象(实际上是原始代码中的一个struct,但.NET InterOp只允许将数据作为类对象导入。我使用System.Runtime.InteropServices。分配和释放内存的Marshal方法,但它可能会留下垃圾,导致一切崩溃。

现在,我应该在Settings类中实现IDisposable方法(它是不受管理的吗?)。如果是这样,我如何处理作为UnmanagedType.ByValTStr编组的字符串以及如何处理Settings对象?

using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
class Settings
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)]
internal string d;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
internal string t;
internal int b;
}

[DllImport(".\\foobar.dll", EntryPoint = "getSettings")]
private static extern int apiGetSettings(IntPtr pointerToSettings);

void GetSettings(ref Settings settings)
{
int debug = 0;

// Initialize a pointer for the structure and allocate memory
IntPtr pointerToSettings = Marshal.AllocHGlobal(43);

// Connect the pointer to the structure
Marshal.StructureToPtr(settings, pointerToSettings, true);

// Point the pointer
debug = apiGetSettings(pointerToSettings);

// Copy the pointed data to the structure
Marshal.PtrToStructure(pointerToSettings, settings);

// Free the allocated memory
Marshal.FreeHGlobal(pointerToSettings);
}
有帮助吗?

解决方案

不,您不需要实现IDisposable。您的Settings类是一个托管类(这些属性仅用于运行时),并且将被垃圾回收。

我的第一个猜测:你要分配43个字节,但是你的两个字符串加起来超过70个字节(记住,除非你在古老的Win98 / Me上,一个字符的大小是2个字节),所以你'重新分配不够。使用Marshal.SizeOf来动态确定结构的大小。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top