我正在使用C#编写一个程序,该程序使用了一个C++库,由于某些原因我需要分配一个非托管缓冲区并将其传递给该库。在C#中是否有方法可以实现这一点?
基本上我只需要在C#中执行类似于malloc的操作...
谢谢
我正在使用C#编写一个程序,该程序使用了一个C++库,由于某些原因我需要分配一个非托管缓冲区并将其传递给该库。在C#中是否有方法可以实现这一点?
基本上我只需要在C#中执行类似于malloc的操作...
谢谢
试试这样做:
using System;
using System.Runtime.InteropServices;
class Example
{
static void Main()
{
IntPtr pointer = Marshal.AllocHGlobal(1024);
}
}
这个代码使用了 Marshal.AllocHGlobal
方法:
使用指定的字节数从进程的非托管内存中分配内存。
FreeHGlobal()
方法释放它。同时,为了避免异常,您可能希望创建一个实现 IDisposable
接口的包装类来分配内存,这样您就可以在 using
语句中分配内存,在 Dispose
方法中释放内存。 - Ron Warholicstatic unsafe void PerformOperation()
{
byte[] buf = new byte[1024];
fixed (void* ptr = &buf[0])
{
SomeUnmanagedFunction(new IntPtr(ptr));
}
}
static void PerformFabulousTrick()
{
byte[] buf = new byte[1024];
fixed (void *ptr = &buf[0])
{
SetBuffer(ptr, buf.Length);
}
FillBuffer(); // puts data in buf - NOT - may crash hard
}
你这样做只会自找麻烦。在这种情况下,你可能想使用GCHandle,它可以将托管对象固定在堆中。但这也可能会带来麻烦,因为你需要及时取消固定,否则就有可能造成堆碎片。
总的来说,我建议确保正确地P/Invoke到函数中,这样可能的话,marshaller就可以为你完成这项工作。相比GlobalAlloc,我更喜欢fixed,因为其范围更清晰。我无法确定我最不喜欢GlobalAlloc和GCHandle中的哪一个,因为它们都要求你做更多的工作,因为GC或语言不能替你完成这些工作。
// Demonstrate how to call GlobalAlloc and
// GlobalFree using the Marshal class.
IntPtr hglobal = Marshal.AllocHGlobal(100);
Marshal.FreeHGlobal(hglobal)
public static void* AlignedAlloc (UIntPtr byteCount, UIntPtr alignment);
这个方法是对C aligned_alloc API或者类似于Win32上的_aligned_malloc的平台相关的对齐分配API的一个薄包装。
当然,在这种情况下没有垃圾回收。为了避免内存泄漏,必须自己释放内存,使用"AlignedFree"。