Я пишу программу в С#, которая использует библиотеку С++, и по какой-то причине мне нужно выделить неуправляемый буфер, чтобы передать его в lib. Есть ли способ сделать это в С#? В принципе мне просто нужно сделать malloc в С#...
Спасибо
Я пишу программу в С#, которая использует библиотеку С++, и по какой-то причине мне нужно выделить неуправляемый буфер, чтобы передать его в lib. Есть ли способ сделать это в С#? В принципе мне просто нужно сделать malloc в С#...
Спасибо
Попробуйте что-то вроде этого:
using System;
using System.Runtime.InteropServices;
class Example
{
static void Main()
{
IntPtr pointer = Marshal.AllocHGlobal(1024);
}
}
Здесь используется метод Marshal.AllocHGlobal
:
Выделяет память из неуправляемой памяти процесса, используя указанное количество байтов.
Для этого также можно использовать массив байтов.
Вы делаете это, используя небезопасную процедуру и фиксированный оператор:
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 или язык не будут делать это за вас.
Вот как нам нужно назначать и освобождать неуправляемую память, используя определенное количество байтов.
// Demonstrate how to call GlobalAlloc and
// GlobalFree using the Marshal class.
IntPtr hglobal = Marshal.AllocHGlobal(100);
Marshal.FreeHGlobal(hglobal)