簡體   English   中英

在c#中將對象列表轉換為字節數組

[英]Convert a List of objects to a byte array in c#

我有這個結構定義:

public struct ChangedByte
{
    public byte R;
    public byte G;
    public byte B;
    public int x;
    public int y;
}

我創建了一個:

List<ChangedByte> testme = new List<ChangedByte>();

(並添加了項目)

我將其轉換為數組:

ChangedByte[] alpha = testme.ToArray();

我有這個功能,我在SO上發現了類似的問題:

byte[] StructureToByteArray(object obj)
{
    int len = Marshal.SizeOf(obj);
    byte[] arr = new byte[len];
    IntPtr ptr = Marshal.AllocHGlobal(len);
    Marshal.StructureToPtr(obj, ptr, true);
    Marshal.Copy(ptr, arr, 0, len);
    Marshal.FreeHGlobal(ptr);
    return arr;
}

我稱之為:

byte[] test = StructureToByteArray(alpha);

我收到錯誤:

類型'new_encoder.Form1 + ChangedByte []'不能作為非托管結構封送; 不能計算有意義的大小或偏移量。

我想將一個對象列表轉換為一個字節數組(並可能避免序列化,因為它往往會增加數組的大小)

可以嗎?

額外:

我試過將Struct修改為:

public struct ChangedByte
{
    [MarshalAs(UnmanagedType.LPWStr)]
    public byte R;
    [MarshalAs(UnmanagedType.LPWStr)]
    public byte G;
    [MarshalAs(UnmanagedType.LPWStr)]
    public byte B;
    [MarshalAs(UnmanagedType.LPWStr)]
    public int x;
    [MarshalAs(UnmanagedType.LPWStr)]
    public int y;
}

但仍然是同樣的錯誤。

您可以使用以下方法:

static byte[] ArrayToBytes<T>(T[] array) where T : struct
{
    IntPtr ptr = IntPtr.Zero;
    try
    {
        int len = Marshal.SizeOf(typeof(T));
        int totalLen = array.Length * len;
        ptr = Marshal.AllocHGlobal(len);
        for (int i = 0; i < array.Length; i++)
        {
            Marshal.StructureToPtr(array[i], ptr + i * len, false);
        }
        var bytes = new byte[totalLen];
        Marshal.Copy(ptr, bytes, 0, totalLen);
        return bytes;
    }
    finally
    {
        if (ptr != IntPtr.Zero)
            Marshal.FreeHGlobal(ptr);
    }
}

static T[] ArrayFromBytes<T>(byte[] bytes) where T : struct
{
    IntPtr ptr = IntPtr.Zero;
    try
    {
        int len = Marshal.SizeOf(typeof(T));
        int count = bytes.Length / len;
        ptr = Marshal.AllocHGlobal(bytes.Length);
        Marshal.Copy(bytes, 0, ptr, bytes.Length);
        T[] array = new T[count];
        for (int i = 0; i < count; i++)
        {
            array[i] = Marshal.PtrToStructure<T>(ptr + i * len);
        }
        return array;
    }
    finally
    {
        if (ptr != IntPtr.Zero)
            Marshal.FreeHGlobal(ptr);
    }
}

並像這樣使用它們:

byte[] test = ArrayToBytes(alpha); // serialize
ChangedByte[] alpha2 = ArrayFromBytes<ChangedByte>(test); // deserialize

在這種情況下,由於您不僅要轉換結構,而且還要轉換結構數組,因此需要循環遍歷數組並轉換每個項目。 使用指針算法在緩沖區中移動並添加項目。

public static byte[] StructureArrayToByteArray(ChangedByte[] objs)
{
    int structSize = Marshal.SizeOf(typeof(ChangedByte));
    int len = objs.Length * structSize;
    byte[] arr = new byte[len];
    IntPtr ptr = Marshal.AllocHGlobal(len);
    for (int i = 0; i < objs.Length; i++ ) {
        Marshal.StructureToPtr(objs[i], ptr + i*structSize, true);
    }
    Marshal.Copy(ptr, arr, 0, len);
    Marshal.FreeHGlobal(ptr);
    return arr;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM