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.