Entwickler-Ecke
Basistechnologien - structs in byte-array kopieren und umgekehrt
Codeexplorer - Fr 27.07.07 13:09
Titel: structs in byte-array kopieren und umgekehrt
Hallo zusammen,
ich möchte mit einer externen Hardware über USB eine Reihe von Telegrammen austauschen. Die Daten lese und schreibe ich über eine DLL als Byte-Array. Den Aufbau Telegramme habe ich als struct-Typen in meinem Code hinterlegt. Die Strukturen sind sehr unterschiedlich aufgebaut: Sie haben unterschiedliche Anzahl von Elementvariablen, unterschiedlich lange Elementvariablen etc..
Da es eine ganze Menge Telegramme sind, möchte ich beim Umkopieren nicht jede Elementvariable einzeln anfassen müssen, sondern würde das ganze gerne im Block umkopieren können (struct in array und umgekehrt).
Ich habe mir schon mal die Klassen Bitconverter und Marshal angeschaut, bin da aber nicht so richtig fündig geworden. Weiß da jemand eine elegante Möglichkeit oder muß ich jetzt einfach tiefer in das Thema "unmanaged code" einsteigen ?
Grüße
Oliver
Codeexplorer - Mo 30.07.07 10:10
Titel: Zwischenstand
Ein Dankeschön an vinh2b und Codeproject.
Der Code unten ist zwar noch nicht getestet, aber so ähnlich könnte es gehen.
Unschön ist aber noch, dass man die Größe des Byte-Arrays im zugehörigen Attribut
hart codieren muss.
Außerdem muss ich für jedes Telegramm eine eigene Methode setTelStructureByArr
und setArrayByStructure anlegen. - Eine Menge kopierter Code. Hmm, hmmm ...
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37:
| [StructLayout(LayoutKind.Sequential)] public struct TelInitData { public byte telNr; public byte slavesCnt1; public byte slavesCnt2; }
public class InitTel { private TelInitData data; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] private byte[] telInitArray; public Init() { telinitArray = new byte[3]; }
public void setTelStructureByArr(byte[] arr) { IntPtr ptData = Marshal.AllocHGlobal(3); Marshal.Copy(arr, 0, ptData, 3); data = (TelInitData)Marshal.PtrToStructure(ptData, typeof(TelInitData)); Marshal.FreeHGlobal(ptData); }
public void setArrayByStructure(TelInitData dataStruc) { IntPtr ptData = Marshal.AllocHGlobal(3); Marshal.StructureToPtr(data, ptData, true); Marshal.Copy(ptData, telInitArray, 0, 3); Marshal.FreeHGlobal(ptData ); } } |
Kha - Mo 30.07.07 12:07
Wenn du die Daten sowieso an eine unmanaged Dll übergibts, wozu benötigst du dann überhaupt das managed Array? Genügt dir nicht einfach der Pointer?
Codeexplorer - Mo 30.07.07 12:44
Guter Hinweis - da werde ich 'mal 'drüber nachdenken.
Der Beispielcode den ich nutze, benutzt eine managed DLL, die wiederum
auf eine unmanaged DLL zugreift. Vielleicht sollte ich gleich die
Original(unmanaged)-Dll ohne Umwege verwenden ...
PS: In diesem Zusammenhang war:
C#-Quelltext
1:
| [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] |
wahrscheinlich sogar unnötig. Das kommt vom vielen Abkupfern und wenig
denken. :wink:
Nachtrag: Nochmal Danke für den Hinweis. Ich werde nun wohl doch die
unmanaged DLL direkt verwenden. Das ist zwar ein bisschen aufwändiger,
aber dafür lernt man mehr dabei ...
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!