Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - MethodAddress führt zu exception/zugriffverletzung
Carlo91 - So 12.09.10 13:26
Titel: MethodAddress führt zu exception/zugriffverletzung
Hallo,
nach langer Delphi pause arbeite ich jetzt wieder an einem kleinen privaten projekt und schon gibt es die ersten probleme^^ Ich programmiere ein Client programm, der Client emfängt vom Server befehle und parameter, in diesem Format 'befehl#parameter1#parameter2#parameterN'. Ich Splite mir den String zu einem String array, soweit funktioniert auch alles! Dann habe ich für jeden befehl eine Methode erstellt also:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| type TClient = class(TForm) ... procedure befehl(parameter: array of String); procedure befehl1(parameter: array of String); procedure befehl2(parameter: array of String); ... end; |
Wenn ich jetzt per MethodAddress mir "die Adresse des befehls" hole und die methode dann aufrufe bekomme ich in der Methode zugriffsverletzungen wenn diese auf andere Objekte des Clients zugreifft (z.B. Button1). Ich habe mal ein kleines Beispiel programm erstellt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure clickbtn(data: String); private public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); var cb: procedure (data: String) of Object; begin @cb :=Nil; @cb :=MethodAddress('clickbtn'); if (@cb <> Nil) then begin cb('test'); end; end;
procedure TForm1.clickbtn(data: String); begin ShowMessage(data); Button2.Enabled :=True; Button2.Click; Button2.Enabled :=False; end;
procedure TForm1.Button2Click(Sender: TObject); begin ShowMessage('Hallo Welt!'); end;
end. |
Meine frage ist jetzt was mache ich falsch? Und habe ich die funktionweise von MethodAddress überhaupt richtig verstanden? Ich freue mich auf eure antworten und hilfe ;-)!
Mit freundlichen Grüßen
Thorben
Tranx - So 12.09.10 14:53
Hallo,
das funktioniert auch ohne Methoaddress:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TForm1.Button1Click(Sender: TObject); var cb: procedure (data: String) of Object; begin cb :=clickbtn; if (@cb <> Nil) then begin cb('test'); end; end; |
jaenicke - So 12.09.10 15:12
Carlo91 hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| var cb: procedure (data: String) of Object; begin @cb :=Nil; @cb :=MethodAddress('clickbtn'); if (@cb <> Nil) then begin cb('test'); | |
Das Problem ist ganz einfach:
Du holst dir die Adresse, dir fehlt aber der zweite Zeiger, nämlich der zu den Daten sprich deinem Objekt.
Denn wie der Name dieser Klassenmethode bereits sagt bekommst du nur die Adresse der Methode, mehr nicht. Das heißt du musst das ganze z.B. in eine TMethod Variable packen und dort zusätzlich zu der Codeadresse, die du über MethodAdress bekommst, auch noch den Datenpointer, also den Objektpointer ausfüllen.
Dann kannst du auch auf Daten des Objekts zugreifen.
// EDIT:
Was schreib ich hier eigentlich, steht doch alles in der Dokumentation... :roll:
http://docwiki.embarcadero.com/VCL/de/System.TObject.MethodAddress
Tranx - So 12.09.10 15:34
Hallo, und bitte sehr, warum funktioniert das mit meinem Beispiel? Die Prozedur Clickbtn ist ja - soweit ich weiß - kompatibel mit einer Prozedurvariablen, wie sie in der Prozedur Button1click definiert wurde. Daher müsste das Beispiel durch einfache Zuordnung der Prozedur zur Variablen cb klappen. Ich habe es ausprobiert. Es klappt.
jaenicke - So 12.09.10 16:08
Tranx hat folgendes geschrieben : |
| Hallo, und bitte sehr, warum funktioniert das mit meinem Beispiel? Die Prozedur Clickbtn ist ja - soweit ich weiß - kompatibel mit einer Prozedurvariablen, wie sie in der Prozedur Button1click definiert wurde. |
Das ist gerade keine Prozedurzeiger, sondern ein Methodenzeiger. Ein Methodenzeiger wie er dort deklariert ist enthält die Adresse plus die Daten. Also die Adresse der Prozedur plus die des Objekts, zu dem die Methode gehört.
Da du die Methode diesem Methodenzeiger direkt zuweist, weist du auch das Objekt mit zu. Deshalb klappt das dort.
Carlo91 - So 12.09.10 17:00
Danke, mit TMedthod funktioniert es in meinem Beispiel projekt! In meinem richtigen Projekt zwar noch nicht aber den fehler werde ich wohl selbst finden.
Mit freundlichen Grüßen
Thorben
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!