在c#中分配“非托管”内存

时间:2010-04-15 19:58:41

标签: c# memory unmanaged

我在c#中编写一个使用C ++库的程序,由于某种原因,我需要分配一个非托管缓冲区来将它传递给lib。有没有办法在c#中做到这一点? 基本上我只需要在C#中做一个malloc ...

由于

3 个答案:

答案 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)