C#不安全值类型数组的字节数组转换 [英] C# unsafe value type array to byte array conversions

查看:178
本文介绍了C#不安全值类型数组的字节数组转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用扩展方法浮动数组转换成字节数组:

I use an extension method to convert float arrays into byte arrays:

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

据我所知,阵列是指向上的类型和元素的数目的信息相关联的存储器。另外,在我看来,有没有从和一个字节数组而不复制与上面的数据做一个转换的方式。

I understand that an array is a pointer to memory associated with information on the type and number of elements. Also, it seems to me that there is no way of doing a conversion from and to a byte array without copying the data as above.

我有没有理解这一点?难道甚至是不可能写IL而不复制数据,以创建从一个指针,类型和长度的数组?

Have I understood this? Would it even be impossible to write IL to create an array from a pointer, type and length without copying data?

编辑:感谢您​​的答案,我学到了一些基本原则,得到了尝试新花样

Thanks for the answers, I learned some fundamentals and got to try out new tricks!

最初接受戴维·兰德曼的答案,我发现,虽然他辉煌StructLayout黑客确实字节数组转换为浮动阵列,它不工作,周围的其他方法之后。为了证明:

After initially accepting Davy Landman's answer I found out that while his brilliant StructLayout hack does convert byte arrays into float arrays, it does not work the other way around. To demonstrate:

[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看到两个阵列具有相同的长度。如果结构是从浮点数据创建,字节数组的长度刚好过短。

It seems that the CLR sees both arrays as having the same length. If the struct is created from float data, the byte array's length is just too short.

推荐答案

是的,类型信息和数据在相同的内存块,所以除非你覆盖在float数组类型的信息来欺骗系统是不可能的它的字节数组。这将是一个非常丑陋的黑客攻击,并可以很容易地炸毁...

Yes, the type information and data is in the same memory block, so that is impossible unless you overwrite the type information in a float array to fool the system that it's byte array. That would be a really ugly hack, and could easily blow up...

下面是如何可以转换彩车没有不安全code,如果你喜欢:

Here's how you can convert the floats without unsafe code if you like:

public static byte[] ToByteArray(this float[] floatArray) {
	int len = floatArray.Length * 4;
	byte[] byteArray = new byte[len];
	int pos = 0;
	foreach (float f in floatArray) {
		byte[] data = BitConverter.GetBytes(f);
		Array.Copy(data, 0, byteArray, pos, 4);
		pos += 4;
	}
	return byteArray;
}

这篇关于C#不安全值类型数组的字节数组转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆