Hallo, habe folgendes Thema, aus einem Webserver und einem I2C Bus wird jeweils ein eigener Befehlsbuffer gefüllt, der in einem gemeinsamen Interpreter analysiert werden soll. <code> dim strBuffer1 as string*127 Dim BufferBytes(128) As Byte At strBuffer1 Overlay dim strBuffer2 as string*127 Dim BufferBytes(128) As Byte At strBuffer2 Overlay .. Call sInterpreter(strBuffer1) ... Call sInterpreter(strBuffer2) sub sInterpreter(strBuffer) ... end sub </code> Wie kann ich hier auf die einzelnenBytes über Overlay zugreifen?? Bin momentan irgendwie planlos
Über den Index?? Du hast ja dim strBuffer1 as string*127 Dim BufferBytes(128) As Byte At strBuffer1 Overlay das bedeutet, die beiden Variablen liegen übereinander also auch den gleichen RAM-Zellen. Wenn Du nun strBuffer1="test" machst, dann liegt der ASCII-Wert in: BufferBytes(1) = 116 ("t") BufferBytes(2) = 101 ("e") BufferBytes(3) = 115 ("s") BufferBytes(4) = 116 ("t") anders herum geht genau so, nur das ein String mit dem Zeichen 0 abgeschlossen wird, also BufferBytes(5) = 0 (NUL)
@weinbauer, ja - danke für die Info - so gehts auch, das Besondere - hab ich leider im ersten Posting nicht so genau ausgedrückt - liegt im Zugriff in der Subroutine sInterpreter, denn hier kann einerseits der strBuffer1 oder der strBuffer2 übergeben werden - und auch hier möchte ich auf die einzelnen Bytes zugreifen.
Hallo Manfred S., an dieser Fragestellung bin ich auch schonmal gescheitert. Habs dann umgangen und ein Bit/Byte übergeben anhand dessen entschieden wird, mit welcher Variable es weitergeht. lG ich
Manfred S. schrieb: > aus einem Webserver und einem I2C Bus wird jeweils > ein eigener Befehlsbuffer gefüllt, Das widerspricht dem Ansatz mit "overlay". Solche exotischen Spielereien sollte man nur nutzen, wenn es gar nicht anders geht, und man genau weiß, was man da tut. Manfred S. schrieb: > das Besondere - hab ich leider im ersten Posting nicht so genau > ausgedrückt - liegt im Zugriff in der Subroutine sInterpreter, denn hier > kann einerseits der strBuffer1 oder der strBuffer2 übergeben werden - Die Übergabe eines Parameters an eine Funktion ist eigentlich seit Erfindung der alleresten prozeduralen Programmiersprache DAS Standardkonzept überhaupt. Manfred S. schrieb: > und auch hier möchte ich auf die einzelnen Bytes zugreifen. Dann mach das doch einfach. Innerhalb von sInterpreter geht das mit strBuffer(index). Oliver
sorry, wie ist denn die Sub deklariert? declare sub sInterpreter(byref strBuffer2 as string) oder declare sub sInterpreter(byval strBuffer2 as string) letzteres wäre hanebüchen, dann gehts nämlich erstens nicht mit der Overlayvariable, weil ja der Inhalt von strbuffer in den Frame kopiert wird, zudem brauch die kopiererei noch unnötige Rechenzeit weil ja die Strings eh schon als globale Variablen deklariert wurden. Bei ersterem kannst Du zwar auf das Array zugreifen, musst aber der Sub auch mitteilen welches es nun sein soll ... macht auch wenig Sinn, da der String eh global deklariert ist. Die sinnvollste Variante ist die von "Name" beschriebene, nur ein Flag zu übergeben und in der Sub dann das Flag zu verarbeiten welches Array / Sting nun verarbeitet werden soll.
Oliver schrieb: > Dann mach das doch einfach. Innerhalb von sInterpreter geht das mit > strBuffer(index). Ja, es ist möglich auf die Einzelbytes des Argumentes zuzugreifen. Aber dann solltest Du dem TE vielleicht auch noch sagen wie, denn mit der Logik des gezeigten Codes wird's eben nicht klappen.
Die Sub ist so definiert: declare sub sInterpreter(byref strBuffer as string) Danke für die vielen Rückmeldungen, geb Oliver recht, nur so einfach ist der Zugriff über den Index natürlich nicht, hab jetzt 3 Ansätze: 1) Ansatz mit Flag, welche Variable übergeben wird: interessanter Ansatz, aber dann muss ich erst in der Subroutine wieder zwischen den beiden Variablen unterscheiden 2) die Lösung von MWS - eigentlich genial, ich habe den Link soeben gefunden http://bascom-forum.de/showthread.php?3039-Übergabe-eines-Arrays-an-eine-Sub-oder-Funktion&s=587d925f63a1152846bbc74e35f27b2d aber über die Hilfe von Bascom wär ich da nicht draufgekommen 3) mit varptr sollte es auch irgendwie gehen
Manfred S. schrieb: > declare sub sInterpreter(byref strBuffer as string) Das ist in diesem Fall eben unbrauchbar. Der Link wird Dir nur begrenzt helfen, denn Du willst einen String übergeben und nicht ein Array. Overlay ist hier keine sinnvolle Option. Aber das hilft Dir:
1 | Declare Sub StrSub(S As Byte) |
2 | |
3 | S = "Hallo" |
4 | $notypecheck |
5 | StrSub S |
6 | $typecheck |
7 | ... |
8 | Sub StrSub(S) |
9 | S(2) = "*" |
10 | End Sub |
Mit Byref, was übrigens Standard ist und nicht extra angegeben werden muss, wird ein Zeiger übergeben. Nur wird sich Bascom beschweren, da die übergebene Variable sich vom definierten Typ unterscheidet. Das lässt sich aber abstellen. Zugriff mit VarPtr(), INP(), OUT() ginge auch, ist aber zu kompliziert.
Danke, MWS, das mit dem $notypecheck ist super - und das der Stringzugriff dann so einfach wird auch. Hab jetzt aber mein Programm weiterentwickelt und gemerkt, dass ich sowohl für Serielle als auch I2C mit einem ByteArray statt einem String auskomme. ByRef schreibe ich zur Dokumentation immer dazu, ganz einfach weil z.B. Excel VBA wie Bascom defaultmäßig ByRef hat, .NET allerdings genau umgekehrt - so gilt: sicher ist sicher.. <code> $regfile = "m644def.dat" $crystal = 8000000 $swstack = 128 $hwstack = 128 $framesize = 128 $baud=19200 Config Serialin = Buffered , Size = 127 , Bytematch = 13 Enable Interrupts Declare Sub Sinterpreter(byref Arr As Byte , Byref Bytlaenge As Byte) 'immer erstes Element übergeben Dim I As Byte Dim Lngcode As Long '**************************** Globale Buffer-Variablen, Interpretervariablen Dim Bytarri2c(128) As Byte Dim Strtext As String * 127 Dim Strzahl As String * 127 'max. 10 Stellen, aber zum Abfangen von Fehleingaben Do 'Logik: shared RAM lese und wenn neue Bytes, dann SInterpreter aufrufen ' I = 17 'Länge der empfangenen Bytes, hier nur Beispiel ' Call Sinterpreter(bytarri2c(1) , I) '0-Terminierung des Strings nicht erforderlich! Loop Serial0charmatch: I = _rs_bufcountr0 - 1 Call Sinterpreter(_rs232inbuf0(1) , I) Clear Serialin Return Sub Sinterpreter(byref Arr As Byte , Byref Bytlaenge As Byte) 'immer erstes Element übergeben 'Achtung: wenn I für Bytlänge übergeben wird, wird I auch gleich geändert 'Befehle, z.B. Code12345678 oder 4711 oder X343 Strzahl = "" Strtext = "" For I = 1 To Bytlaenge 'trenne Ziffern und Text If Arr(i) >= 48 And Arr(i) <= 57 Then Strzahl = Strzahl + Chr(arr(i)) Else Strtext = Strtext + Chr(arr(i)) End If Next I Lngcode = Val(strzahl) Select Case Strtext Case "x" Case "y" Case Else 'nur Zahl oder 0 oder falscher Befehl End Select End Sub </code>
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.