拡張メソッドを使用して、float配列をバイト配列に変換します。
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ハックはバイト配列をfloat配列に変換しますが、その逆は機能しないことがわかりました。実証するために:
[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は、両方の配列が同じ長さであると見なしているようです。構造体がfloatデータから作成されている場合、バイト配列の長さが短すぎます。