| |
VB.NET - Ein- und UmsteigerRe: Bytes in Structure einordnen | | | Autor: Manfred X | Datum: 15.01.10 18:13 |
| Hallo!
Schau Dir mal die Überladungen von Array.Copy an
Du kannst genau angeben ab welchem Index kopiert werden soll.
Hier die Parameterliste aus der Dokumentation:
Du musst SourceIndex mit dem Startindex im QuellArray belegen
und den Destinationindex in deinem Fall mit 0.
sourceArray
Typ: System..::.Array
Das Array, das die zu kopierenden Daten enthält.
sourceIndex
Typ: System..::.Int32
Eine 32-Bit-Ganzzahl, die den Index im sourceArray angibt, ab dem kopiert werden soll.
destinationArray
Typ: System..::.Array
Das Array, das die Daten empfängt.
destinationIndex
Typ: System..::.Int32
Eine 32-Bit-Ganzzahl, die den Index im destinationArray angibt, ab dem gespeichert werden soll.
length
Typ: System..::.Int32
Eine 32-Bit-Ganzzahl, die die Anzahl der zu kopierenden Elemente darstellt. | |
Bytes in Structure einordnen | | | Autor: CodenameReese | Datum: 14.01.10 22:54 |
| Hallo,
Habe ein Problem mit Bytes die ich in meinem Programm via UDP geschickt bekomme^^
Und zwar sollen diese Bytes in ein Structure "eingeordnet" werden... hab sowas noch nie gemacht und kann mir auch nicht wirklich vorstellen wie das gehen soll^^ Nun habe ich im Internet schon einiges über Sachen wie z.B. Copymemory (VB6) oder halt diese Marshal-Klasse (VB.NET) gelesen, welche ja anscheinend bestimmte Datenblöcke kopieren können! Nun weiß ich leider nicht genau wie das funktionieren soll bzw. ob das überhaupt der richtige Weg hierfür wäre^^
Hier mal mein Beispielcode:
Public Structure Packet
Dim Time() As Byte
Dim Var1 As Byte
Dim Var2 As Single
Dim Var3 As Single
Dim ID As Long
End Structure
Public Class Form1
Private Port As Integer = 12345
' Funktion ist nur kopiert^^ (CodeProject)
Private Function BulidStr(ByVal Buff() As Byte, ByVal MyType As System.Type) _
As Object
Dim MyGC As GCHandle = GCHandle.Alloc(Buff, GCHandleType.Pinned)
Dim Obj As Object = Marshal.PtrToStructure(MyGC.AddrOfPinnedObject, _
MyType)
Return Obj
MyGC.Free()
End Function
Private Sub StartListener()
Dim Listener As New UdpClient(Port)
Dim EndPoint As New IPEndPoint(IPAddress.Any, Port)
Dim Pack As Packet
Try
Dim Data As Byte() = Listener.Receive(EndPoint)
Pack = BulidStr(Data, Pack.GetType)
Catch ex As Exception
MsgBox(ex)
Finally
Listener.Close()
End Try
End Sub
End Class Hierbei bekomme ich aber einen Fehler:
"AccessViolationException: Es wurde versucht, im geschützten Speicher zu lesen oder zu schreiben. Dies ist häufig ein Hinweis darauf, dass anderer Speicher beschädigt ist."
Andererseits glaube ich irgendwie das ich hier völlig auf dem falschen Weg bin Weil nur um diese Bytes in eine Struktur einzuordnen brauche ich doch keine Datenblöcke aus dem Speicher zu kopieren oder?
Bitte helft mir
MfG Reese | |
Re: Bytes in Structure einordnen | | | Autor: Drapondur | Datum: 15.01.10 03:10 |
| Hallo,
Du musst bei Packet angeben, wie groß das Array Time sein soll. Angenommen Time soll 12 Bytes groß sein, dann:
Public Structure Packet
<MarshalAs(UnmanagedType.ByValArray, Sizeconst:=12)> Dim Time As Byte()
Dim Var1 As Byte
Dim Var2 As Single
Dim Var3 As Single
Dim ID As Long
End Structure Ferner solltest Du besser schreibenPrivate Function BulidStr(ByVal buff() As Byte, ByVal myType As System.Type) As _
Object
'Sicherheitscheck, dass wir genug Daten im Buffer haben
If buff.Length < Marshal.SizeOf(myType) Then
Throw New ArgumentException(String.Format("Das Array hat nicht genug" & _
"Elemente, um ein Objekt vom Typ {0} zu erstellen", myType))
End If
Dim MyGC As GCHandle = GCHandle.Alloc(buff, GCHandleType.Pinned)
'Try-Finally, um MyGC.Free() auch bei Fehler auszuführen
Try
Dim p As IntPtr = MyGC.AddrOfPinnedObject()
Dim o As Object = Marshal.PtrToStructure(p, myType)
Return o
Finally
MyGC.Free()
End Try
End Function Ciao
D. | |
Re: Bytes in Structure einordnen | | | Autor: Manfred X | Datum: 15.01.10 04:55 |
| Hallo!
Innerhalb des Framework solltest Du besser managed-Objects verwenden.
In das (zuvor deklarierte) Bytearray "Time" kopierst Du die Werte direkt
hinein: Array.Copy(Data, <StructureInstance>.Time, <StructureInstance>.Time.Length)
Das Kopieren von Bytes in eine integrierte Datenstruktur
(in Deinem Fall Single und Long) kannst Du mit dem BitConverter
erledigen.
Ausführlich ist das erklärt in einem VB-Archiv-Workshop (Abschnitt 2):
http://www.vbarchiv.net/workshop/workshop_102-bersicht-ueber-die-hilfsmittel-fuer-operationen-auf-bit-ebene-vb2005-2008.html
Solltest du trotzdem das Marshalling vorziehen, ist die Deklaration der Datenstruktur
mit einem "StructLayout" zu versehen, um die Abfolge und Anordnung der Elemente
im Speicher z.B. für den Kopiervorgang sicherzustellen.
<System.Runtime.InteropServices.StructLayout _
(System.Runtime.InteropServices.LayoutKind.Sequential)> _
Public Structure Packet
.....
MFG
Manfred
Beitrag wurde zuletzt am 15.01.10 um 05:03:44 editiert. | |
Re: Bytes in Structure einordnen | | | Autor: CodenameReese | Datum: 15.01.10 17:21 |
| Danke erstmal!
Genau das meinte ich mit "Ich glaub ich bin auf dem falschen Weg" *auch wenn er nicht ganz so falsch war* Weil die Lösung von "Drapondur" gefällt mir eindeutig besser
Aber zwei Fragen hätte ich dazu noch^^ Erstens zu dem Array.Copy... Wie mach ich das wenn ich mehrere Byte-Arrays hintereinander habe? Weil ich muss ja nirgends einen Startpunkt angeben (für den Kopiervorgang wird ja nur die Länge benötigt!?) Und zweitens wie gebe ich diese Byte-Array aus? Hab es schon mit "System.Text.Encoding.UTF8/ASCII.GetString" versucht dabei bekomm ich aber nur komische Zeichen^^
Hier mal wieder ein Beispielcode:
Public Class Form1
Private Const Port As Integer = 12345
Private Packet As Test
Private Structure Test
Dim Var1() As Byte
Dim Var2() As Byte
Dim Var3() As Byte
Dim Var4 As Byte
Dim Var5 As Single
Dim Var6 As Long
End Structure
Private Sub StartListener()
ReDim Packet.Var1(3)
ReDim Packet.Var2(3)
ReDim Packet.Var3(1)
Dim Done As Boolean = False
Dim Listener As New UdpClient(Port)
Dim EndPoint As New IPEndPoint(IPAddress.Any, Port)
Dim Pt As Integer
Try
While Not Done
Dim Data As Byte() = Listener.Receive(EndPoint)
Pt = 0
Array.Copy(Data, Packet.Var1, Packet.Var1.Length)
Pt += Packet.Var1.Length
Array.Copy(Data, Packet.Var2, Packet.Var2.Length)
Pt += Packet.Var2.Length
Array.Copy(Data, Packet.Var3, Packet.Var3.Length)
Pt += Packet.Var3.Length
Packet.Var4 = Data(Pt)
Pt += 1
Packet.Var5 = BitConverter.ToSingle(Data, Pt)
Pt += 4
Packet.Var6 = BitConverter.ToInt64(Data, Pt)
Pt += 8
MsgBox(Encoding.ASCII.GetString(Packet.Var1, 0, _
Packet.Var1.Length)
End While
Catch ex As Exception
MsgBox(ex.Message)
Finally
Listener.Close()
End Try
End Sub
End Class MfG Reese | |
Re: Bytes in Structure einordnen | | | Autor: CodenameReese | Datum: 17.01.10 19:28 |
| Ahh Okay Danke!
Hatte da zwar schon geschaut aber hab malwieder diese kleinen Pfeile vom IntelliSense übersehen wenn es mehrere Möglichkeiten gibt Sorry^^
MfG Reese | |
Re: Bytes in Structure einordnen | | | Autor: CodenameReese | Datum: 19.01.10 11:25 |
| Halli Hallo, Ich bin es schonwieder
Häng jetzt an einer anderen Stelle fest... und zwar ist doch bei einer UDP-Verbindung nicht dafür gesorgt das die Pakete in der richtigen Reihenfolge bei mir ankommen oder? So nun versuch ich das ganze mit "Buffern" zu lösen... denn alle Pakete enthalten eine Zeit zu der sie verschickt wurden dh es kann vorkommen das ein Paket das zu einem späteren Zeitpunkt verschickt wurde vor dem "neueren" bei mir ankommt^^
Mein Ansatz sieht so aus (Beispielcode):
Public Class Form1
Private MainThread As Thread = New Thread(AddressOf StartListener)
Private Port As Integer = 12345
Private ID As Integer = 1
Private Done As Boolean = False
Private Packet As Test
Private Structure Test
Dim Time As UInteger
Dim Var1 As Single
Dim ID As Integer
End Structure
Private Sub Form1_Load([...]) Handles MyBase.Load
MainThread.Start
End Sub
Private Sub Form1_FormClosing([...]) Handles MyBase.FormClosing
Done = True
MainThread.Abort
End Sub
Private Sub StartListener()
Dim Buffer1 As Test
Dim Buffer2 As Test
Dim Listener As New UdpClient(Port)
Dim EndPoint As New IPEndPoint(IPAddress.Any, Port)
Dim Pt As Integer
Try
While Not Done
Dim Data As Byte() = Listener.Receive(EndPoint)
Pt = 0
Buffer1.Time = BitConverter.ToUInt32(Data, Pt)
Pt += 4
Buffer1.Var1= BitConverter.ToSingle(Data, Pt)
Pt += 4
Buffer1.ID = BitConverter.ToInt32(Data, Pt)
Pt += 4
If Buffer1.ID = ID Then
Select Case Buffer1.Time
Case Is > Buffer2.Time
Buffer2 = Buffer1
Case Else
Buffer2 = Buffer1
Buffer1 = Packet
End Select
Packet = Buffer2
End If
End While
Catch ex As Exception
MsgBox(ex.Message)
Finally
Listener.Close()
End Try
End Sub
End Class Mein Problem dabei ist... das auf diesem Wege ja irgendwie trotzdem als erstes das "alte" Paket verarbeitet wird oder auch nur ein Teil davon^^ (Verarbeitet wird dann praktisch "Packet") Außerdem wenn ich das so mache geht mir ja das "alte" Paket flöten
Und da bin ich mit meinem Latein am Ende... vll hab ich auch nur irgendwie in Denkfehler!?
Brauch ich denn sowas überhaupt? Weiß ja nicht was zu einem UDPClient so alles dazugehört
MFG Reese | |
Re: Bytes in Structure einordnen | | | Autor: CodenameReese | Datum: 19.01.10 12:06 |
| Okay Soll heißen ich kann dieses ganze Sortieren gleich lassen^^ Hmm also brauch ich nichts weiter als das was ich schon hab für eine UDP-Verbindung?! Na okay dann, dann auf jedenfall Danke!
MFG Reese | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
sevAniGif (VB/VBA)
Anzeigen von animierten GIF-Dateien
Ab sofort lassen sich auch unter VB6 und VBA (Access ab Version 2000) animierte GIF-Grafiken anzeigen und abspielen, die entweder lokal auf dem System oder auf einem Webserver gespeichert sind. Weitere InfosTipp des Monats TOP Entwickler-Paket
TOP-Preis!!
Mit der Developer CD erhalten Sie insgesamt 24 Entwickler- komponenten und Windows-DLLs. Die Einzelkomponenten haben einen Gesamtwert von 1605.50 EUR...
Jetzt nur 599,00 EURWeitere Infos
|