Подтвердить что ты не робот

Выделение "неуправляемой" памяти в С#

Я пишу программу в С#, которая использует библиотеку С++, и по какой-то причине мне нужно выделить неуправляемый буфер, чтобы передать его в lib. Есть ли способ сделать это в С#? В принципе мне просто нужно сделать malloc в С#...

Спасибо

4b9b3361

Ответ 1

Попробуйте что-то вроде этого:

using System;
using System.Runtime.InteropServices;

class Example
{
    static void Main()
    {
        IntPtr pointer = Marshal.AllocHGlobal(1024);
    }
}

Здесь используется метод Marshal.AllocHGlobal:

Выделяет память из неуправляемой памяти процесса, используя указанное количество байтов.

Ответ 2

Для этого также можно использовать массив байтов.

Вы делаете это, используя небезопасную процедуру и фиксированный оператор:

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/Invoking в функции, чтобы, возможно, маршаллер мог выполнить эту работу за вас. Мне нравится исправляться лучше, чем GlobalAlloc, поскольку его объем ясен. Я не могу решить, что мне больше всего нравится GlobalAlloc и GCHandle. Оба требуют, чтобы выполнить больше работы, поскольку GC или язык не будут делать это за вас.

Ответ 3

Вот как нам нужно назначать и освобождать неуправляемую память, используя определенное количество байтов.

// Demonstrate how to call GlobalAlloc and 
// GlobalFree using the Marshal class.
IntPtr hglobal = Marshal.AllocHGlobal(100);
Marshal.FreeHGlobal(hglobal)