Вы также можете использовать байтовый массив для этого.
Это делается с помощью небезопасной процедуры и фиксированного оператора:
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 или язык не сделают этого за вас.