我在 C# 中使用 IntPtr,从 C++ 项目中获取对象数组。
为此,我使用 Marshal.AllocHGlobal 方法分配了所需的内存,并将 C++ 中的完整数组复制到 ptr 中。
问题是我正在提升指针,移动到数组中的下一个对象。
我的问题是: 在使用 Marshal.FreeHGlobal 方法之前,我是否必须恢复 IntPtr 的第一个值?
这是代码
public List<DirEntry> getDirEntries()
{
int dirEntrySize = Marshal.SizeOf(typeof(DirEntry));
int bufferSize = 28 * dirEntrySize;
IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
CppToCsharpAdapter.getDirEntries(this.myDiskPointer, buffer);
DirEntry dirEntry = new DirEntry();
List<DirEntry> dirEntries = new List<DirEntry>();
for (int i = 0; i < 28; i++)
{
Marshal.PtrToStructure(buffer, dirEntry);
buffer += dirEntrySize;
}
Marshal.FreeHGlobal(buffer);
return dirEntries;
}
最佳答案
您必须创建原始指针的拷贝,供以后使用。在这种情况下,它被称为电流:
public List<DirEntry> getDirEntries()
{
int dirEntrySize = Marshal.SizeOf(typeof(DirEntry));
int bufferSize = 28 * dirEntrySize;
IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
CppToCsharpAdapter.getDirEntries(this.myDiskPointer, buffer);
IntPtr current = buffer;
DirEntry dirEntry = new DirEntry();
List<DirEntry> dirEntries = new List<DirEntry>();
for (int i = 0; i < 28; i++)
{
Marshal.PtrToStructure(current, dirEntry);
current += dirEntrySize;
}
Marshal.FreeHGlobal(buffer);
return dirEntries;
}
但是,还有另一种可能性,无需通过使用 IntPtr.Add()
使用指针的显式拷贝:
public List<DirEntry> getDirEntries()
{
int dirEntrySize = Marshal.SizeOf(typeof(DirEntry));
int bufferSize = 28 * dirEntrySize;
IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
CppToCsharpAdapter.getDirEntries(this.myDiskPointer, buffer);
DirEntry dirEntry = new DirEntry();
List<DirEntry> dirEntries = new List<DirEntry>();
for (int i = 0; i < 28; i++)
{
Marshal.PtrToStructure(IntPtr.Add(buffer, i * dirEntrySize), dirEntry);
}
Marshal.FreeHGlobal(buffer);
return dirEntries;
}
请记住,您的代码包含潜在的内存漏洞。您应该将代码包装在 try/finally block 中。如果指针不为零,则在 finally block 中再次释放内存块:
public List<DirEntry> getDirEntries()
{
int dirEntrySize = Marshal.SizeOf(typeof(DirEntry));
int bufferSize = 28 * dirEntrySize;
IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
try
{
CppToCsharpAdapter.getDirEntries(this.myDiskPointer, buffer);
DirEntry dirEntry = new DirEntry();
List<DirEntry> dirEntries = new List<DirEntry>();
for (int i = 0; i < 28; i++)
{
Marshal.PtrToStructure(IntPtr.Add(buffer, i * dirEntrySize), dirEntry);
}
}
finally
{
if (buffer != IntPtr.Zero)
Marshal.FreeHGlobal(buffer);
}
return dirEntries;
}
关于c# - 提升指针后释放 IntPtr 分配的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23948947/