Forum: PC-Programmierung [C#] Byte Array zu Struct kopieren


von Draco (Gast)


Lesenswert?

Kann ich in C# ein Byte-Array direkt in ein Struct kopieren?!
Ich meine das so:

Mein Struct-Beispiel:
1
struct MyStruct
2
{
3
   float Wert1;
4
   float Wert2;
5
   sbyte Wert3;
6
}

das Bytearray hätte quasi 9 Felder... 0-4 Float Wert 1, 5-8 Float Wert 
2, 9 UINT8 Wert 3.

Das Arrray welches ich direkt in eine Struct wandeln möchte ist halt nur 
etwas größer (255 Bytes) mit unterschiedlichen Werten.

Oder muss ich alles per Hand in meine Struct schreiben?!

von sbe_15 (Gast)


Lesenswert?

Schau dir mal die Methoden der Klasse "Convert" an. Denen kann man meine 
ich auch Byte-Arrays mitgeben. Die ganze Struct in einem Rutsch zu 
konvertieren wird wohl nicht gehen, du kannst es aber Feld für Feld 
machen (und dies z.B: in einer Methode deiner struct kapseln).

von Draco (Gast)


Lesenswert?

sbe_15 schrieb:
> Schau dir mal die Methoden der Klasse "Convert" an. Denen kann man meine
> ich auch Byte-Arrays mitgeben. Die ganze Struct in einem Rutsch zu
> konvertieren wird wohl nicht gehen, du kannst es aber Feld für Feld
> machen (und dies z.B: in einer Methode deiner struct kapseln).

Ich hab das bis jetzt auch so gemacht. Hab da nun aber eine schöne 
Funktion gefunden die mir diese Arbeit abnimmt:
1
using System.Runtime.InteropServices;
2
3
4
//...
5
6
static object ByteArrayToStruct(byte[] array, int offset, Type structType)
7
{
8
  if (structType.StructLayoutAttribute.Value != LayoutKind.Sequential)
9
  throw new ArgumentException("structType ist keine Struktur oder nicht Sequentiell.");
10
11
  int size = Marshal.SizeOf(structType);
12
13
  byte[] tmp = new byte[size];
14
15
  if (offset > 0)
16
    Array.Copy(array, offset, tmp, 0, size);
17
  else
18
    tmp = array;
19
20
  GCHandle structHandle = GCHandle.Alloc(tmp, GCHandleType.Pinned);
21
  object structure = Marshal.PtrToStructure(structHandle.AddrOfPinnedObject(), structType);
22
  structHandle.Free();
23
24
  return structure;
25
}

Kopiert wird es dann wie folgt:
1
MyStruct TestStruct;
2
3
TestStruct = (MyStruct)ByteArrayToStruct(TestBytearray, 0, typeof(MyStruct));

von HerrGesangsverein (Gast)


Lesenswert?

Hallo,

kleiner Hinweis noch:
Das struct muss mit den Attributen:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
struct MyStruct
{
}
eingeleitet werden, damit a)durch die Feldorientierung keine Lücken 
entstehen und b) strings nicht mit UTF8 drin leigen (außer man will 
das).

Klugerweise fängt die Kopiermethode von Draco ei falsches Layout ab und 
wirft eine Exception, aber der User weiß vielleicht nicht, wie er die 
Exception verhindern kann.

Viele Grüße

von Draco (Gast)


Lesenswert?

Ja das stimmt, das hab ich vergessen zu schreiben. Ist der sequentielle 
Zugriff bei C# aber nicht Standard? (Das mit dem ANSI ist allerdings nen 
großer Faupat es nicht zu erwähnen :D )

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.