Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mi Jul 09, 2025 02:41

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Do Apr 05, 2007 10:58 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 31, 2005 11:02
Beiträge: 432
Wohnort: Rheinlandpfalz
Hi Leute,
habe folgendes Problem:
Ich habe eine Variable Buffer vom Typ Pointer und weise ihm jetzt Speicher zu.
Dann wird der Buffer gefüllt und nun möchte ich ihn wieder auslesen.

Code:
  1. Var buffer : Pointer;
  2.  
  3. GetMem(buffer, NL_MAX_PACKET_LENGTH);
  4. nlRead(FClient[i].Socket, buffer^, NL_MAX_PACKET_LENGTH);
  5.  
  6. // hier möchte ich zuerst mal ein Integer auslesen (4 Bytes),
  7. // und dann z. B.: einen 32 Byte großen String etc.
  8.  
  9. FreeMem(buffer);


Wie kann ich einen Integer, String, Float etc. aus einer beliebigen Stelle (oder vom Anfang) auslesen
und in eine entsprechende Variable des Typs speichern ?

Momentan mache ich es so, dass ich den Buffer in einen MemoryStream schreibe, und diesen dann mit Read(bla, SizeOf(bla))
auslese. Dadurch verbrauche ich aber doppelt so viel Speicher obwohl das wahrscheinlich gar nicht nötig ist :wink:

_________________
http://texelviews.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 05, 2007 11:32 
Offline
DGL Member

Registriert: Mo Dez 20, 2004 08:58
Beiträge: 442
Wohnort: Mittweida (Sachsen)
Nachdem Buffer ein Zeiger ist, zeigt er auf das nullte Byte Deines reservierten Speichers, d.h. in der variable Buffer ist ein Integer drin. Wenn Du nun auf das vierte Byte zugreifen willst, musst Du einfach das Offset zum Buffer addieren, also z.B.:
Code:
  1.  
  2.   MyInt=Integer((buffer+4)^);
  3.  

Obs mit dem Syntax so stimmt weiss ich jetzt nicht ausm Kopf, aber im Prinzip sollte es so gehen.

_________________
Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 05, 2007 11:48 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Sidorin: Ja eigentlich stimmt das.

Ich denke aber du wirst mit Strings ein Problem bekommen. Denn Strings sind an und für sich auch nur Pointer. Wenn der String IMMER 32 Bytes groß ist dann kannst du auf eine Größenangabe verzichten. Sonst ist diese ein muss. Allerdings kannst du nicht eben nach String casten. Du musst dem String mittels SetLength die größe zuweisen und kannst dann die entsprechenden Bytes ausslesen. So ähnlich wie bei Streams.
Code:
  1. SetLength(MyString, 32);
  2. Move(Pointer^, MyString[1], 32);


Ich persönlich versuche aber fast immer mit typisierten Pointern zu arbeiten. Aber wenn die Struktur sich verändern kann dann geht das natürlich nicht. Evtl wären dort aber Methoden praktisch mit denen du das Kappseln kannst. Also GetInteger(Pointer) liefert einen Integer und setzt den Pointer automatisch weiter. Inc(Pointer, 4). Das macht das Handling ungemein einfacher. Wichtig dabei aber einen Pointer auf den Anfang speichern. Damit du den wieder freigeben oder sonst etwas machen kannst. Der übergebene ist nur Temporär.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 05, 2007 15:58 
Offline
DGL Member

Registriert: Mo Dez 20, 2004 08:58
Beiträge: 442
Wohnort: Mittweida (Sachsen)
Im Grunde sind Pointer nix anderes als Lesezeichen, d.h.: dein Pointer zeigt auf den Anfang des Buches. Willst Du nun vier Seiten weiter hinten zu lesen anfangen, steckst Du sozusagen das Lesezeichen nicht am Anfang, sondern auf Seite vier in das Buch (Inc(Pointer,4)). Oder Du sagst 'fang vier Seiten hinter meinem Lesezeichen an zu lesen' ((Pointer+4)^).
Strichrechnung ist bei Pointern zugelassen und nötig. Man kann sogar Pointer aufaddieren, wobei sich mir hier der Sinn ein bisschen verschließt (ausser ich hab nen 2. Pointer aufs Offset, aber da eignet sich wohl ein normaler Integer besser).

_________________
Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 05, 2007 22:56 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 31, 2005 11:02
Beiträge: 432
Wohnort: Rheinlandpfalz
hmm... also die Idee ist gut. So steht es auch in der Delphi-Hilfe.
Funktioniert aber komischerweise nicht !?

Bei
Code:
  1. Inc(buffer, 4);
kommt: [Pascal Fehler] NLServer.pas(151): E2001 Ordinaltyp erforderlich

Probiere ich das:
Code:
  1. myInt := Integer((buffer+4)^);
kommt folgender Fehler: [Pascal Fehler] NLServer.pas(153): E2015 Operator ist auf diesen Operandentyp nicht anwendbar


\":?:\" \":?:\" \":?:\"

Liegt es vielleicht an meinem Delphi (Turbo Delphi 2006) ? Wer das hat kann ja mal testen.
Entweder ich seh den Wald vor lauter Bäumen nicht oder hier läuft was komplett schief... \":?\"

Zumindest das funktioniert:
Code:
  1. Move(buffer^, myInt, 4);

So kann ich wenigstens den ersten Integer auslesen. Ist aber letztendlich leider zu wenig!

_________________
http://texelviews.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 05, 2007 23:03 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
myInt := PInteger(Integer(buffer)+4)^;


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 05, 2007 23:09 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 31, 2005 11:02
Beiträge: 432
Wohnort: Rheinlandpfalz
Cool :D
Danke für die schnelle Antwort! Funktioniert wunderbar :wink:
Warum man da aber noch so was drumherumbauen muss ist mir schleierhaft...

_________________
http://texelviews.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 05, 2007 23:47 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Im Gegensatz zu C gibt es in Delphi keine impliziten Konvertierungen zwischen Integer und Zeigern. Andererseits kann man auch keinen Integer zu einem Zeiger addieren. Daher erst in einen Integer konvertieren, den Wert addieren und wieder zurück in einem Zeiger. Diese Konvertierungen kosten allerdings nichts. Sie sind nur für den Compiler da.
Besser wäre gleich einen Zeiger auf ein Array zu nehmen.

buffer:PIntegerArray;

Dann geschieht diese Berechnung automatisch.
Man könnte direkt schreiben buffer[i]. Das entspricht PInteger(Integer(buffer)+i*4) .


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Apr 06, 2007 00:52 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Lars: Da kleben auch Strings drinne und da ist ein PIntegerArray wohl nicht so praktisch. Ich persönlich bin aber eh nicht so ein Fan von Pointer auf Arrays. Wenn das Array zu klein definiert ist und wie ich die Bereichsprüfung anstellt, dann bekommt man mitunter Fehler die eigentlich nicht nötig wären. Und ich meine irgendwo einen Typen gesehen zu haben der nur mit 32.000 Elementen definiert war.

MatReno: Anstelle eines Pointers kannst du auch einen PByte benutzen. Dann klappts auch mit dem Inc. Der erhöht im übrigen um Count * die Size des PointerTypens. Also bei einem PInteger würde Inc(Blah, 1) Blah automatisch um 4 Byte erhöhen.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 8 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.013s | 17 Queries | GZIP : On ]