Entwickler-Ecke
Windows API - Inhalt einer bestimmten Adresse ändern
LastRide - Sa 05.07.08 21:58
Titel: Inhalt einer bestimmten Adresse ändern
Hi,
Ich habe mal eine Frage und zwar wollte ich gerne den Inhalt einer Adresse ändern. Dazu weiß ich ist es notwendig einen Zeiger zu definieren :stolzsei: xD.
Wenn ich das richtig Verstanden habe definiere Ich den Zeiger so
Delphi-Quelltext
1: 2:
| var zeiger: ^TDaten; |
Und wenn ich es jetzt weiter Richtig verstehe muss ich ihm im Heap Speicher reservieren was wie folgt funktioniert.
Jetzt kommt aber der Punkt an dem ich nicht weiter weiß und zwar wie lege ich jetzt die Adresse auf den Zeiger, lese den Inhalt aus und veränder diesen dann?
Wäre euch sehr dankbar wenn mir da jemand auf die Sprünge helfen könnte.
MfG
LastRide
Tilman - Sa 05.07.08 22:05
Sobald du Speicher mit new reservierst, ist die Adresse auf dem Zeiger. Das machst du damit ja gerade ;)
Um nun den Inhalt zuzuweisen (und auszulesen) musst du dereferenzieren:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| var zeiger : ^Integer;
begin new(zeiger); zeiger^ := 5; ShowMessage(IntToStr(zeiger^)); .. |
LastRide - Sa 05.07.08 22:09
Das heißt ich setze für "5" jetzt einfach meine Adresse ein und schon wird mir der Inhalt angezeigt?
MfG LastRide
Edit: Ich habe falsch gedacht, sry. Wie Schaffe ich es denn dem Zeiger eine bestimmte Adresse zu Übergeben also nicht mit New(Zeiger) ihm seine eigene zu geben ?
Tilman - Sa 05.07.08 22:19
Mit dem @ Operator. (new brauchst du dann
nicht) Beispiel:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| var daten: TMeineDaten; zeiger: ^TMeineDaten; begin daten := TMeineDaten.Create;
zeiger := @daten; |
Wichtig: wenn man einen Zeiger auf eine Lokale Variable setzt, so muss man bedenken dass diese dann nach dem Funktionsaufruf wieder freigegeben wird. Soll der Zeiger auch nach dem Funktionsaufruf noch auf gütlige Daten zeigen, so muss der Speicherplatz entweder mit new reserviert werden, oder per @ auf eine
Globale Variable gesetzt werden.
// edit:
Ürbigens, hier findest du ein Tutorial zum Thema "Pointer" dass kaum Wünsche übrig lässt:
http://www.manuel-poeter.de/index.php?site=tutorials
LastRide - Sa 05.07.08 22:28
Also zum Beispiel wennich auf die Adresse "04110BA4" zugreifen möchte einfach
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| begin
Zeiger := @04110BA4; ShowMessage(IntToStr(Zeiger^)); Dispose(Zeiger);
end; |
machen und das wars ?
MfG
LastRide
Tilman - Sa 05.07.08 22:32
Nein. Wenn du die Adresse hast (ungewöhnliche Vorgehensweise allerdings), musst du sie direkt angeben (mit Pointer und Integer casten), ohne @ davor. Allerdings, soweit ich weiß sind die Adressen die man hier bekommt unter Delphi keine echten Adressen. Möglicherweise funktioniert das also nicht so wie du dir das Vorstellst.
Beispiel:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| var str: String;
procedure TForm1.Button1Click(Sender: TObject); var zeiger : ^String;
begin zeiger := Pointer(StrToInt(edit1.text)); caption := zeiger^; end;
procedure TForm1.Button2Click(Sender: TObject); begin edit1.Text := IntToStr(Integer(@str)); end;
procedure TForm1.FormCreate(Sender: TObject); begin str := 'Hallo'; end; |
Der Sinn dieses Beispieles ist natürlich gering.
LastRide - Sa 05.07.08 22:40
Ob gering oder nicht ;) es hilft mir weiter zu verstehen xD. Muss ich in deinem Beispiel also nur das hallo bei
mit der Adresse Austauschen und fertig ist der Zeiger auf die Adresse ?
MfG
LastRide
Tilman - Sa 05.07.08 23:19
Fast ^^ du must den inhalt des editfeldes ändern (edit1.text) ^^
LastRide - So 06.07.08 11:50
Nachdem ich mir das pdf in deinem Link durch gelesen habe habe ich etwas bemerkt ;). Und ich denke das wir aneinander vorbei geredet haben :). Also nochmal zum Verständnis:
entspricht
kann ich dann nicht einfach bei der Adresse, ich verwende jetzt mal das Beispiel,
den Code so abändern ?
MfG LastRide
Yogu - So 06.07.08 12:30
LastRide hat folgendes geschrieben: |
kann ich dann nicht einfach bei der Adresse, ich verwende jetzt mal das Beispiel,
den Code so abändern ? |
Nein, aber fast:
Delphi-Quelltext
1:
| Zeiger := Pointer($04110BA4); |
Du musst den Integer-Wert erst in einen Zeiger umwandeln.
LastRide - So 06.07.08 13:01
Okay damit ist meine Frage dann schon zum teil Beantwortet ;). Nur wie schaffe ich es jetzt den Wert auf den der Pointer zeigt auszulesen und zu ändern. Da wäre ich euch für eine Hilfe Stellung sehr verbunden.
MfG LastRide
Yogu - So 06.07.08 13:12
Das hat doch
Tilman schon erklärt. Wenn du aber einen Zeiger ohne Typ hast, musst du ihn erst in einen typisierten Zeiger umwandeln:
Delphi-Quelltext
1:
| PInteger(Zeiger)^ := 5; |
Zuerst wird der untypisierte Zeiger in einen Zeiger auf einen Integer umgewandelt, dann dereferenziert und schließlich wird die 5 ins Ziel geschrieben. Natürlich musst du statt
PInteger den gewünschten Zeigertyp eintragen.
uall@ogc - Mo 07.07.08 13:15
nehmen wir also an du hast einen Record der so aussieht:
Delphi-Quelltext
1: 2: 3: 4: 5:
| TPerson = packed record name: String[20]; alter: byte; end; PPerson = ^TPerson; |
und du weißt das an Adresse 0x00401000 so eine TPerson stehen soll dann macht man das so:
Delphi-Quelltext
1: 2: 3: 4: 5:
| var myPerson = PPerson; begin myPerson := Pointer($00401000); myPerson.Name := 'Peter'; if myPerson.Alter = 60 then |
seit irgendeiner Delphi Version muss man das dref ^ nicht mehr angeben, wenns nicht gehen sollte:
Delphi-Quelltext
1: 2: 3: 4: 5:
| var myPerson = PPerson; begin myPerson := Pointer($00401000); myPerson^.Name := 'Peter'; if myPerson^.Alter = 60 then |
Hidden - Mo 07.07.08 13:50
uall@ogc hat folgendes geschrieben: |
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| var myPerson: PPerson; begin myPerson := Pointer($00401000); myPerson.Name := 'Peter'; if myPerson.Alter = 60 then | |
packed bedeutet, dass die Daten in einem festen Block stehen müssen und nicht verteilt sein können, wie es auf der Festplatte manchmal der Fall ist :?:
kann es sein, dass es hier im Forum unheimlich viele Daniels gibt?^^
uall@ogc - Mo 07.07.08 15:11
packed bedeutet einfach, dass die Daten direkt hintereinander stehen und nicht zum Lese / Schreibzugriff optimiert sind (sondern um Speicher zu sparen), da Integers z.b. an einer durch 4 teilbaren Adresse schneller zu lesen sind (obwohl ich gerade auch meine Bedenkten habe, dass der Record auch dann im speicher mindestens bei einer durch 8 Teilbaren Adresse steht zwecks Standardalignment 8)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!