Преобразовать указатель C uint8_t в байтовый массив C # - PullRequest
1 голос
/ 31 октября 2010

Я экспортировал следующую функцию C для вызова в файле DLL.

uint8_t* _stdcall GetCurrentImage();

Теперь я хочу вызвать эту функцию в C #, чтобы получить растровое изображение. Как я могу это сделать?

Заранее спасибо!

Ответы [ 3 ]

3 голосов
/ 31 октября 2010

Вам нужно будет знать точное количество возвращаемых байтов и размеры растрового изображения (высота, ширина и кодировка).Затем вы можете объявить его в C # как:

[DllImport("yourlib.dll")]
private static extern IntPtr GetCurrentImage();

Получаемый вами IntPtr может использоваться с Marshal.Copy, чтобы получить необработанные байты:

byte[]  buffer = new byte[length];
IntPtr beginPtr = GetCurrentImage();
Marshal.Copy(beginPtr, buffer,0,length);

Наконец, объявите Bitmap с размерами вашего изображения и используемым PixelFormat (если это нестандартный пиксельный формат, вам, возможно, придется выполнить какое-то преобразование самостоятельно).Затем вы можете скопировать данные в необработанные байты растрового изображения, используя LockBits , чтобы получить экземпляр BitmapData , который указывает на необработанные данные растрового изображения.

0 голосов
/ 15 января 2013

Если вы хотите продолжать работать в небезопасном контексте даже в C #, вы также можете упростить все, минуя Marshal и IntPtrs, следующим образом:

[DllImport("Library.dll")]
internal static unsafe extern Byte* GetCurrentImage();

Имейте в виду, что это всегда хорошая практика - вставлять все свои импорты в статический класс NativeMethods и объявлять их как внутренние.

0 голосов
/ 31 октября 2010

Общая стратегия для подобных вещей - передать буфер и заставить функцию заполнить буфер. В противном случае у вас возникнут проблемы с распределением выделенной памяти; другими словами, у вас будет утечка памяти.

Так что у вас должны быть такие функции C ...

uint32_t _stdcall GetCurrentImageSize();
void _stdcall GetCurrentImage(uint8_t* buffer, int offset, int bufferSize);

А потом в C # вы бы сделали что-то вроде ...

var buffer = new byte [ GetCurrentImageSize() ];
fixed (byte* b = &buffer[0])
    GetCurrentImage(b, 0, buffer.Length);

// 'buffer' now contains the image
...