我在c#中编写一个使用C ++库的程序,由于某种原因,我需要分配一个非托管缓冲区来将它传递给lib。有没有办法在c#中做到这一点? 基本上我只需要在C#中做一个malloc ...
由于
答案 0 :(得分:39)
尝试这样的事情:
using System;
using System.Runtime.InteropServices;
class Example
{
static void Main()
{
IntPtr pointer = Marshal.AllocHGlobal(1024);
}
}
这使用Marshal.AllocHGlobal
方法:
使用指定的字节数从进程的非托管内存中分配内存。
答案 1 :(得分:8)
您也可以使用字节数组。
您可以使用不安全的例程和固定语句来执行此操作:
static unsafe void PerformOperation()
{
byte[] buf = new byte[1024];
fixed (void* ptr = &buf[0])
{
SomeUnmanagedFunction(new IntPtr(ptr));
}
}
问题 - 这是一个重要问题 - 是SomeUnmanagedFunction在返回并且代码退出固定块后不允许触摸该指针。所以如果你做这样的事情:
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 /函数,这样也许编组人员可以为你做这项工作。我喜欢修复比GlobalAlloc更好,因为它的范围很明确。我无法决定哪个最不喜欢GlobalAlloc和GCHandle。由于GC或语言不适合您,要求您需要做更多的工作。
答案 2 :(得分:2)
这就是我们需要使用特定字节数来分配和释放非托管内存的方法。
// Demonstrate how to call GlobalAlloc and
// GlobalFree using the Marshal class.
IntPtr hglobal = Marshal.AllocHGlobal(100);
Marshal.FreeHGlobal(hglobal)