C#如何从IntPtr获取Byte []

时间:2011-03-30 13:26:15

标签: c# byte bytearray intptr

我有一个.dll(不是我自己的)有一个委托。该委托回调函数是:
“CallBackFN(ushort opCOde, IntPtr有效载荷,uint size,uint localIP)”

如何将IntPtr转换为Byte []?我认为有效载荷实际上是Byte []。如果它不是Byte []而且它是其他东西我会丢失一些数据?

6 个答案:

答案 0 :(得分:40)

如果是字节:

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

如果不是字节,则Marshal.Copy中的size参数是数组中元素的数量,而不是字节大小。因此,如果你有一个int []数组而不是byte []数组,你必须除以4(每个int的字节数)才能获得要复制的正确数量的元素,假设你通过回调传递的size参数指的是字节数。

答案 1 :(得分:21)

答案 2 :(得分:15)

如果您需要演奏,请直接使用:

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);
        }
    }
}

答案 3 :(得分:6)

根据this Stack Overflow question,您可以执行以下操作:

var byteArray = new byte[dataBlockSize];
System.Runtime.InteropServices.Marshal.Copy(payload, byteArray, 0, dataBlockSize);

答案 4 :(得分:4)

答案 5 :(得分:0)

Span<byte>可能是更好的解决方案,因为它提供了字节数组中所需的大多数功能。由于不需要分配和复制到新的缓冲区,因此速度更快,并且由于不必直接使用指针而更加安全。

IntPtr ptr = ... ; 
int ptrLength = ...; 


unsafe
{
    Span<byte> byteArray = new Span<byte>(ptr.ToPointer(), ptrLength);

    for (int i = 0; i < byteArray.Length; i++ )
    {
        // Use it as normalarray array ;
        byteArray[i] = 6;
    }

    // You can always get a byte array . Caution, it allocates a new buffer
    byte[] realByteArray = byteArray.ToArray();
}

它包含在.NET Core 2.1和.NET Framework 4.5 +和.NET Core 2.0 +的nuget package (System.Memory)中;