我有一个.dll文件(不是我自己的),其中包含一个委托。这个委托的回调函数是:
"CallBackFN(ushort opCOde, IntPtr payload, uint size, uint localIP)"
我该如何将IntPtr转换为Byte[]?我认为payload实际上是Byte[]。如果它不是Byte[],而是其他类型,我会失去一些数据吗?
我有一个.dll文件(不是我自己的),其中包含一个委托。这个委托的回调函数是:
"CallBackFN(ushort opCOde, IntPtr payload, uint size, uint localIP)"
我该如何将IntPtr转换为Byte[]?我认为payload实际上是Byte[]。如果它不是Byte[],而是其他类型,我会失去一些数据吗?
如果它是一个 byte[]
数组:
byte[] managedArray = new byte[size];
Marshal.Copy(pnt, managedArray, 0, size);
如果不是byte[]
,Marshal.Copy方法中的size参数是数组中元素的数量,而不是字节大小。 因此,如果你有一个int[]
数组而不是byte[]
数组,你需要除以4(每个int占用4个字节),才能获得正确的要复制的元素数量,假设回调中传递的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);
}
}
}
你是否研究过 Marshal.Copy 函数?
http://msdn.microsoft.com/zh-cn/library/system.runtime.interopservices.marshal.copy.aspx
根据这个Stack Overflow问题,你可以按照以下方式进行操作:
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包(System.Memory);