Array to Struct und Struct to Array

Wer effizient und schnell Daten serialisieren und deserialisieren möchte stößt mit den gängigen Parsern in .Net häufig auf Probleme. Gerade bei Netzwerkanwendungen ist es wichtig möglichst wenig Zusatzinformationen (am besten keine) zu verschicken. Die meisten Serialisierungsarten, wie etwa XML, haben jedoch jede menge Overhead.
Mit dem Marshaller ist es möglich eine Klasse oder Struktur in ein Array von Bytes zu wandeln. Dabei entsteht keinerlei Overhead. Alle Informationen der Klasse werden der Reihe nach in das Bytearray geschoben. Das ganze funktioniert natürlich auch auf dem umgekehrten Weg. Es ist genauso einfach eine Struktur in ein Bytearray zu marshallen.
class ByteTransform
{
 public static T GetStruct(Byte[] byteArray)
 {
  GCHandle handle = GCHandle.Alloc(byteArray, GCHandleType.Pinned);
  T returnValue = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T);
  handle.Free();

  return returnValue;
 }

 public static byte[] GetByteArray(T structur)
 {
  byte[] returnValue = new byte[Marshal.SizeOf(structur)];
  GCHandle handle = GCHandle.Alloc(returnValue, GCHandleType.Pinned);
  Marshal.StructureToPtr(structur, handle.AddrOfPinnedObject(), false);
  handle.Free();

  return returnValue;
 }
}

Um nun eine Struktur in ein Bytearray zu wandeln ist nur die entsprechende statische Funktion aufzurufen. Das ganze ist auch mit Klassen möglich. Dabei kann zusätzlich angegeben werden wie der Marshaller den Member verarbeitet.
[StructLayout(LayoutKind.Sequential)]
class MyClass
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
string MyString;

[MarshalAs(UnmanagedType.I4)]
Int32 MyInteger;

[MarshalAs(UnmanagedType.U8)]
UInt64 MyUnsignedLong;
}
Bookmark and Share

0 Kommentare:

Kommentar veröffentlichen