如何从IntPtr获取Byte[]的C#代码

57

我有一个.dll文件(不是我自己的),其中包含一个委托。这个委托的回调函数是:
"CallBackFN(ushort opCOde, IntPtr payload, uint size, uint localIP)"

我该如何将IntPtr转换为Byte[]?我认为payload实际上是Byte[]。如果它不是Byte[],而是其他类型,我会失去一些数据吗?


可能重复:https://dev59.com/glXTa4cB1Zd3GeqPzTI1请注意,这是一个可能重复的问题。 - Cody Gray
6个回答

73

如果它是一个 byte[] 数组:

 byte[] managedArray = new byte[size];
 Marshal.Copy(pnt, managedArray, 0, size);
如果不是byte[],Marshal.Copy方法中的size参数是数组中元素的数量,而不是字节大小。 因此,如果你有一个int[]数组而不是byte[]数组,你需要除以4(每个int占用4个字节),才能获得正确的要复制的元素数量,假设回调中传递的size参数是字节数。

谢谢。我认为这就是了。如果数组不是字节,则我将尝试更改“大小”。 - Gabriel
+1 对于答案的前半部分。实际上,另一半我甚至都没看 :) - Bitterblue

25
如果您需要性能,直接使用它:
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);
        }
    }
}


11

根据这个Stack Overflow问题,你可以按照以下方式进行操作:

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

4
数据块大小的数值从哪里获取? - Parthi
@Parthi - 这取决于你正在做什么。块大小将根据你要复制的数据量而异。 - Justin Morgan

9

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包(System.Memory);


你确定这里的ToArray()不会造成分配吗?根据我的测试,似乎会。 - crowder
值得一提的是,ToArray会导致分配和复制内容。 - Manuel Amstutz

4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接