PeekB() - mehrere Bytes auslesen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Sebastian
Beiträge: 322
Registriert: 14.06.2006 16:46
Wohnort: Kiel

PeekB() - mehrere Bytes auslesen

Beitrag von Sebastian »

Ich möchte nicht nur ein einzelnes Byte von einer bestimmten Speicheradresse auslesen, sondern mehrere. Wie kann ich dies erreichen? Der PeekB() Befehl springt doch sicher nicht weiter wie ein Zeiger, oder? Wie kann ich dann auf das 2.,3. und 4. Byte an einer Speicheradresse zugreifen?
(Win 11 64-bit, PB 6.04 und 6.10)
a14xerus
Beiträge: 1440
Registriert: 14.12.2005 15:51
Wohnort: Aachen

Beitrag von a14xerus »

Code: Alles auswählen

var_4_byte.l = Random(1000) ; long variablen sidn 4 byte groß

*speicher = @var_4_byte ; adresse in var *speicher schreiben

byte1.b = PeekB(*speicher) ; byte 1 auslesen
byte2.b = PeekB(*speicher+1) ; byte 2 auslesen
byte3.b = PeekB(*speicher+2) ; byte 3 auslesen
byte4.b = PeekB(*speicher+3) ; byte 4 auslesen

Debug byte1
Debug byte2
Debug byte3
Debug byte4
edit: noch ein wenig erklärung:

variablen haben einerseitz einen wert

Code: Alles auswählen

variable.l = 5
debug variable
aber diese variable muss ja auch irgendwo gespeichert sein.
an diese adresse kommt man mit

Code: Alles auswählen

@variable
wenn man sich nun die adresse der variable holt steht der wert an dieser adresse im speicher, udn zwar zusammenhängend.
wie groß der bereich ist hängt om typ ab.
entweder man nimmt variablen von einem bestimmten typ (zb 32bit long => 4byte, doubble => 8 byte etc) oder man holt sich selber einen speicherbereich

Code: Alles auswählen

allocatememory()
, den man aber auch selbst wieder freigeben muss.
string steehn genau so im speicher.
"nromal" initialisierte strings haben eine dynamische länge, abhängend von der kodiereung (zb utf-8 etc) und halt der stringlänge.
ein 8 zeichen ansi-string belegt 9 byte (8*1byte pro zeichen + 0-byte)
ein 8 zeichen unicodestring belegt 18 byte (8*2byte pro zeichen + 2*0-byte) udn utf hängt von den zeichen an sich ab...

zurück zum zusammenhängenden speicherbereich:

da die adresse den "startpunkt" im speicher angibt, kann man einfach +1, +2, +3, +n zur adresse aufrechnen um die nächsten bytes auszulesen.
Zuletzt geändert von a14xerus am 18.01.2008 16:28, insgesamt 2-mal geändert.
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

PeekB(adresse + relativesOffsetInBytes)

Also so in etwa:

Code: Alles auswählen

*mem = AllocateMemory(16)

; 2. Byte auslesen:
Debug PeekB(*mem + 1)
[EDIT]
Zu langsam.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
inc.
Beiträge: 348
Registriert: 27.10.2004 12:25

Beitrag von inc. »

Peek & Poke sollte man lieber via direkter Speicherzugriffe ersetzen.
Ist zwar weniger Basic-Like und unleserlicher, aber ... markant schneller.

Code: Alles auswählen

*p.Byte = *speicherAdresse

byte1.b = *p\b : *p + SizeOf(Byte) 
byte2.b = *p\b : *p + SizeOf(Byte)
byte3.b = *p\b : *p + SizeOf(Byte)
byte4.b = *p\b 
Oder ....

Code: Alles auswählen

*p.Long = *speicherAdresse

byte1.b = *p\l & $000000FF
byte2.b = *p\l & $0000FF00 >> 8
byte3.b = *p\l & $00FF0000 >> 16
byte4.b = *p\l & $FF000000 >> 24

byte1.b = *p\l & $FF 
byte2.b = (*p\l >> 8  ) & $FF
byte3.b = (*p\l >> 16 ) & $FF
byte4.b = (*p\l >> 24 ) & $FF
Bin hier im Job, daher ausm Kopf, aber bei der LittleEndian ByteOrder müsste das oben so stimmen.

Oder ... noch eleganter á la C/C++

Code: Alles auswählen

Structure BYTEARRAY ;// Sollte mal in PB nativ als Structure integriert werden
  b.b[0]
Endstructure

*p.BYTEARRAY = *speicherAdresse

For i = 0 to #BYTECOUNT -1 ;// Anzahl der zu lesenden Bytes ab der *speicherAdresse
  debug *p\b[i] 
Next i

Zuletzt geändert von inc. am 19.01.2008 19:53, insgesamt 3-mal geändert.
Hier gibts die OOP Option für PureBasic.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

das gehtaber bei Strings nicht

denn wenn ich versuche mit *p\s einen String zu bekommen dann versucht der ja n Pointer des Strings zu finden, aber bei PeekS() steht der String ja direkt da wo man ließt.

Oder habe ich das jetzt falsch verstanden ?
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
inc.
Beiträge: 348
Registriert: 27.10.2004 12:25

Beitrag von inc. »

Die Frage bezog sich ja hier auf Bytes, aber bei Strings müsste das ebenso funktionieren.

Code: Alles auswählen

Structure myString
  StructureUnion
    s.s
    l.l
  EndStructureUnion 
EndStructure

p.myString 
p\l= @string 
Debug p\s 
So kann man ja imho auch Strings aus DLL Funktionen holen ohne jenes PeekS() sofern ich mich richtig erinnere.
Hier gibts die OOP Option für PureBasic.
Antworten