C # как получить Byte [] из IntPtr - PullRequest
34 голосов
/ 30 марта 2011

У меня есть .dll (не моя), у которой есть делегат.Эта функция обратного вызова делегата:
"CallBackFN (ushort opCOde, Полезная нагрузка IntPtr , размер uint, локальный IP-адрес uint)"

Как я могу преобразовать IntPtr в байт []?Я думаю, что полезная нагрузка на самом деле Байт [].Если это не Byte [] и что-то еще, я бы потерял некоторые данные?

Ответы [ 5 ]

43 голосов
/ 30 марта 2011

Если это байты:

 byte[] managedArray = new byte[size];
 Marshal.Copy(pnt, managedArray, 0, size);

Если это не байты, параметр размера в Marshal.Copy - это количество элементов в массиве, а не размер в байтах.Таким образом, если бы у вас был массив int [], а не массив byte [], вам пришлось бы разделить его на 4 (байты на целое), чтобы получить правильное количество копируемых элементов, предполагая, что параметр размера, переданный через обратный вызов, ссылается на# байтов.

21 голосов
/ 30 марта 2011
16 голосов
/ 02 февраля 2015

Если вам нужна производительность, используйте ее напрямую:

unsafe { 
    byte *ptr = (byte *)buffer.ToPointer();

    int offset = 0;
    for (int i=0; i<height; i++)
    {
        for (int j=0; j<width; j++)
        {

            float b = (float)ptr[offset+0] / 255.0f;
            float g = (float)ptr[offset+1] / 255.0f;
            float r = (float)ptr[offset+2] / 255.0f;
            float a = (float)ptr[offset+3] / 255.0f;
            offset += 4;

            UnityEngine.Color color = new UnityEngine.Color(r, g, b, a);
            texture.SetPixel(j, height-i, color);
        }
    }
}
6 голосов
/ 30 марта 2011

Согласно этому вопросу о переполнении стека , вы можете сделать следующее:

var byteArray = new byte[dataBlockSize];
System.Runtime.InteropServices.Marshal.Copy(payload, byteArray, 0, dataBlockSize);
4 голосов
/ 30 марта 2011

Вы можете использовать Метод Marshal.Copy (IntPtr, Byte [], Int32, Int32)

...