【发布时间】:2011-07-26 02:36:32
【问题描述】:
我有一个有委托的 .dll(不是我自己的)。这个委托回调函数是:
"CallBackFN(ushort opCOde, IntPtr payload, uint size, uint localIP)"
如何将 IntPtr 转换为 Byte[]?我认为有效载荷实际上是字节[]。如果不是 Byte[] 而是别的东西,我会丢失一些数据吗?
【问题讨论】:
我有一个有委托的 .dll(不是我自己的)。这个委托回调函数是:
"CallBackFN(ushort opCOde, IntPtr payload, uint size, uint localIP)"
如何将 IntPtr 转换为 Byte[]?我认为有效载荷实际上是字节[]。如果不是 Byte[] 而是别的东西,我会丢失一些数据吗?
【问题讨论】:
如果是byte[] 数组:
byte[] managedArray = new byte[size];
Marshal.Copy(pnt, managedArray, 0, size);
如果不是byte[],则Marshal.Copy中的size参数是数组元素个数,不是字节大小。因此,如果您有一个 int[] 数组而不是 byte[] 数组,则您必须除以 4(每个 int 的字节数)才能获得要复制的正确数量的元素,假设您通过回调传递的 size 参数是指字节数。
【讨论】:
【讨论】:
如果需要性能,直接使用:
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);
}
}
}
【讨论】:
根据this Stack Overflow question,您可以执行以下操作:
var byteArray = new byte[dataBlockSize];
System.Runtime.InteropServices.Marshal.Copy(payload, byteArray, 0, dataBlockSize);
【讨论】:
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) 中;
【讨论】: