C# 如何从 IntPtr 获取 Byte[]

Posted

技术标签:

【中文标题】C# 如何从 IntPtr 获取 Byte[]【英文标题】:C# how to get Byte[] from IntPtr 【发布时间】:2011-07-26 02:36:32 【问题描述】:

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

如何将 IntPtr 转换为 Byte[]?我认为有效载荷实际上是字节[]。如果不是 Byte[] 而是别的东西,我会丢失一些数据吗?

【问题讨论】:

可能重复:***.com/questions/5298930/… 【参考方案1】:

如果是byte[] 数组:

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

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

【讨论】:

谢谢。我觉得这就是。如果数组不是字节,那么我将尝试更改“大小” +1 表示答案的前半部分。真的,另一半没有......我什至没有读过它:)【参考方案2】:

你看过 Marshal.Copy 吗?

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.copy.aspx

【讨论】:

【参考方案3】:

如果需要性能,直接使用:

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

【讨论】:

【参考方案4】:

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

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

【讨论】:

我们从哪里得到 dataBlockSize 值? @Parthi - 这取决于你在做什么。块大小将根据您要复制的数据量而有所不同。【参考方案5】:

Span&lt;byte&gt; 可能是一个更好的解决方案,因为它提供了字节数组所需的大部分功能。它更快,因为您不需要分配和复制到新缓冲区,并且更安全,因为您不必直接使用指针。

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

【讨论】:

你确定这里的 ToArray() 不会导致分配吗?在我的测试中,它似乎是。 值得一提的是,ToArray 导致分配并复制内容docs.microsoft.com/en-us/dotnet/api/…【参考方案6】:

您可以使用Marshal.Copy Method (IntPtr, Byte[], Int32, Int32)

【讨论】:

以上是关于C# 如何从 IntPtr 获取 Byte[]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ReadProcessMemory 获取托盘按钮文本

如何从 C# 中的 Web Api 方法正确获取字节数组?

如何通过 IntPtr 将 c++ 数组编组为 c#

C#已经获取到视频流了,如何播放这个byte[]文件,如何定义缓冲区

我用C#,上一步函数返回了一个IntPtr型的图片指针,我已知图片的长、宽,如何转换成image类。

从 c# 查询 MySQL 返回 System.Byte[]