如何将值struct的数组转换为字节?

时间:2011-12-15 16:25:47

标签: c# .net serialization binary

我有一个System.Array值结构类型,如下所示:

public value struct Position
{
    int timestamp;
    float x;
    float y;
}

Position[] positions = new Position[1000 * 1000];

使用值初始化数组后,如何在不串行化一个项目的情况下获取byte[]内容?

在C ++ / CLI中,我将使用pin_ptr来获取指向数组内容的指针,然后从那里复制数据。我可以在C#中做这样的事情吗?

编辑:我需要将原始数据写入磁盘,就好像它是一个C结构,没有任何序列化。

我将此问题标记为C#以获得更广泛的曝光率,但实际上我正在尝试从IronPython序列化数据,因此这意味着我无法使用任何unsafe C#功能。

3 个答案:

答案 0 :(得分:2)

也许这会有所帮助:

[Serializable()]
    public struct Position
    {
        int timestamp;
        float x;
        float y;
    }


    static void Main(string[] args)
    {
        var positions = new Position[1000 * 1000];
        GetBytes(positions);
    }
    private static byte[] GetBytes(object obj)
    {
        using (var memoryStream = new System.IO.MemoryStream())
        {
            var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            binaryFormatter.Serialize(memoryStream, obj);
            return memoryStream.ToArray();
        }
    }

答案 1 :(得分:1)

我相信这相当于使用不安全的C#代码的C ++ / CLI pin_ptr:

    public static unsafe byte[] GetBytes(Position[] positions)
    {
        byte[] result = new byte[positions.Length * Marshal.SizeOf(typeof(Position))];
        fixed (Position* ptr = &positions[0])
        {
            Marshal.Copy((IntPtr)ptr, result, 0, result.Length);
        }
        return result;
    }

答案 2 :(得分:1)

这是一种不需要不安全代码的方法:

[更新以删除for循环并一次执行副本]

private static byte[] StructureToByteArray(Position[] posArray)
{
    if (posArray == null || posArray.Length == 0)
    {
        return new byte[0];
    }

    var lenOfObject = Marshal.SizeOf(typeof(Position));
    var len = lenOfObject * posArray.Length;
    var arr = new byte[len];

    var handle = GCHandle.Alloc(posArray, GCHandleType.Pinned);
    try
    {
        var ptr = handle.AddrOfPinnedObject();
        Marshal.Copy(ptr, arr, 0, len);
    }
    finally
    {
        handle.Free();
    }

    return arr;
}