我使用一个扩展方法将浮点数组转换为字节数组:
public static unsafe byte[] ToByteArray(this float[] floatArray, int count)
{
int arrayLength = floatArray.Length > count ? count : floatArray.Length;
byte[] byteArray = new byte[4 * arrayLength];
fixed (float* floatPointer = floatArray)
{
fixed (byte* bytePointer = byteArray)
{
float* read = floatPointer;
float* write = (float*)bytePointer;
for (int i = 0; i < arrayLength; i++)
{
*write++ = *read++;
}
}
}
return byteArray;
}
我理解数组是一个指向与元素类型和数量相关联的内存的指针。另外,对我来说,似乎没有办法在不复制数据的情况下将数组与字节数组进行转换。
我理解得对吗?甚至是否不可能编写 IL 从指针、类型和长度创建数组而不复制数据?
编辑:感谢答案,我学到了一些基础知识,并尝试了新技巧!
最初接受了 Davy Landman 的答案后,我发现他的 StructLayout 黑科技虽然可以将字节数组转换为浮点数数组,但无法实现反向转换。举个例子:
[StructLayout(LayoutKind.Explicit)]
struct UnionArray
{
[FieldOffset(0)]
public Byte[] Bytes;
[FieldOffset(0)]
public float[] Floats;
}
static void Main(string[] args)
{
// From bytes to floats - works
byte[] bytes = { 0, 1, 2, 4, 8, 16, 32, 64 };
UnionArray arry = new UnionArray { Bytes = bytes };
for (int i = 0; i < arry.Bytes.Length / 4; i++)
Console.WriteLine(arry.Floats[i]);
// From floats to bytes - index out of range
float[] floats = { 0.1f, 0.2f, 0.3f };
arry = new UnionArray { Floats = floats };
for (int i = 0; i < arry.Floats.Length * 4; i++)
Console.WriteLine(arry.Bytes[i]);
}
似乎CLR将这两个数组都视为具有相同的长度。如果结构体是由浮点数据创建的,则字节数组的长度就太短了。