s k*_*s k 0 c# c++ interop memory-management
我有 C#(核心)和 C++(非托管 DLL)之间的代码互操作。
在 C# using 中分配的内存Marshal.AllocHGlobal()需要在 C# using中释放Marshal.FreeHGlobal()。
在 C++ using 中分配的内存new需要在 C++ using中释放delete。
由于 GC 不再跟踪这些内存处理程序,我可以随时delete或FreeHGlobal()随心所欲吗?
不,你不能只使用任何你想释放内存的方法。您必须使用分配器要求您使用的任何内容。只有分配给定内存块的内存管理器知道如何正确释放该内存块。
例如,文档Marshal.AllocHGlobal()说明:
此方法从 Kernel32.dll 公开 Win32 LocalAlloc 函数。
当 AllocHGlobal 调用 LocalAlloc 时,它会传递一个 LMEM_FIXED 标志,这会导致分配的内存被锁定到位。此外,分配的内存不是零填充的。
以及LocalAlloc()状态的文档:
要释放内存,请使用 LocalFree 函数。使用 GlobalFree 释放用 LocalAlloc 分配的内存是不安全的。
这是什么Marshal.FreeHGlobal()用途:
FreeHGlobal 从 Kernel32.DLL 公开 LocalFree 函数,它释放所有字节,以便您不能再使用 hglobal 指向的内存。
因此,允许 C# 代码使用分配内存Marshal.AllocHGlobal(),然后 C++ 代码使用LocalFree(). 相反,对于 C++ 代码使用分配内存LocalAlloc(LMEM_FIXED),然后对于 C# 代码使用Marshal.FreeHGlobal().
同样,Marshal该类也有一个Marshal.AllocCoTaskMem()方法:
此方法公开 COM CoTaskMemAlloc 函数,称为 COM 任务内存分配器。
分配的内存通过以下CoTaskMemAlloc()方式释放CoTaskMemFree():
释放先前通过调用 CoTaskMemAlloc 或 CoTaskMemRealloc 函数分配的任务内存块。
这是什么Marshal.FreeCoTaskMem()用途:
FreeCoTaskMem 公开 COM CoTaskMemFree 函数,该函数释放所有字节,以便您不能再使用 ptr 参数指向的内存。
因此,允许 C# 代码使用分配内存Marshal.AllocCoTaskMem(),然后 C++ 代码使用CoTaskMemFree(). 相反,对于 C++ 代码使用分配内存CoTaskMemAlloc(),然后对于 C# 代码使用Marshal.FreeCoTaskMem().
现在,话虽如此,C++ 用于其new和delete运算符的内存管理器是实现定义的。不保证(或可能性)new使用LocalAlloc()或CoTaskMemAlloc(),或delete使用LocalFree()或CoTaskMemFree()。
因此,C# 释放任何由 分配的内存new或 C++释放delete由 C# 分配的任何内存都是不合法的。
| 归档时间: |
|
| 查看次数: |
414 次 |
| 最近记录: |