Feedback

C# - Byte-Array in Struktur kopieren

Veröffentlicht von am 2/19/2011
(1 Bewertungen)
Gerade bei der Verwendung von binären Dateien kommt es vor das man auf C(++) Strukturen stößt.
Diese kann man natürlich mit der BinaryReader Klasse einlesen, was aber gerade bei größeren Strukturen recht mühsam sein kann.
Hier eine Alternative. Hier wird das ganze Array quasi "in einem Rutsch" in die Struktur kopiert.
Voraussetzung ist das (in C#) das StructLayout auf LayoutKind.Sequential gesetzt ist.

Diese Funktion ist dafür gedacht Strukturen aus unmanagend Code in eine verwaltete Struktur zu kopieren, nicht zum Deseralisieren von verwalteten Strukturen!

Verwendung:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
struct MyStruct
{
int foo1;
int foo2;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
string fooStr;
}

// ...
byte[] array = // ...

MyStruct myStruct = (MyStruct)ByteArrayToStruct(array, 0, typeof(MyStruct));
/// <summary>
/// Kopiert Daten aus einem Byte-Array in eine entsprechende Strukture (struct). Die Struktur muss ein sequenzeilles Layout besitzen. ( [StructLayout(LayoutKind.Sequential)] 
/// </summary>
/// <param name="array">Das Byte-Array das die daten enthält</param>
/// <param name="offset">Offset ab dem die Daten in die Struktur kopiert werden sollen.</param>
/// <param name="structType">System.Type der Struktur</param>
/// <returns></returns>
static object ByteArrayToStruct(byte[] array, int offset, Type structType)
{
    if (structType.StructLayoutAttribute.Value != LayoutKind.Sequential)
        throw new ArgumentException("structType ist keine Struktur oder nicht Sequentiell.");

    int size = Marshal.SizeOf(structType);
    if (array.Length < (offset + size))
        throw new ArgumentException("Byte-Array hat die falsche Länge.");

    byte[] tmp = new byte[size];
    Array.Copy(array, offset, tmp, 0, size); 

    GCHandle structHandle = GCHandle.Alloc(tmp, GCHandleType.Pinned);
    object structure = Marshal.PtrToStructure(structHandle.AddrOfPinnedObject(), structType);
    structHandle.Free();

    return structure;
}
Abgelegt unter struct, byte, array, Marshal, C, , C++, struktur, binär, datei, unmanagend.

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!