Autor |
Beitrag |
Hami04
Hält's aus hier
Beiträge: 6
|
Verfasst: Mi 12.05.10 09:59
Hallo,
ich habe ein Problem mit Pointern auf Methoden-Pointer.
Ein Methoden-Pointer in Delphi besteht ja aus einem Record mit zwei Pointern: einen auf die Funktion und einen auf das Objekt. Diese Methoden-Pointer möchte ich in eine Struktur packen. Die Struktur nimmt allerdings nur einfache Pointer auf. Ich versuche also, einen Pointer auf den Methoden-Pointer, also auf den Record, zu nehmen und diesen in die Struktur zu packen. Wenn ich den Pointer jetzt dereferenziere bekomme ich einen Zugriffsverletzung.
Hier etwas Beispielcode:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure test type TMethod = procedure of object; var Method: TMethod; Method2: TMethod; pMethod: ^TMethod; begin Method := MyObject.MyMethod; pMethod := @Method; Method2 := pMethod^;
Method; Method2; end; |
Kann sich irgendjemand, das erklären. Ich nämlich leider nicht.
Viele Grüße
Philipp
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 12.05.10 10:04
Gib mal bitte den gemischten Assembler-Code aus dem CPU-Fenster für diese Routine. Dann kann ich Dir sagen, was Delphi da baut. Ich denk mal, der wird einmal zu wenig Dereferenzieren. Aber mehr mit ASM-Code dazu.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Hami04 
Hält's aus hier
Beiträge: 6
|
Verfasst: Mi 12.05.10 10:39
Problem ist gelöst. Es muss ein @@ genommen werden.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure test type TMethod = procedure of object; var Method: TMethod; Method2: TMethod; pMethod: ^TMethod; begin Method := MyObject.MyMethod; pMethod := @@Method; Method2 := pMethod^;
Method; Method2; end; |
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 12.05.10 10:52
Hier der komplette Assemblercode: 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:
| Unit244.pas.38: begin 00457E54 83C4F0 add esp,-$10 Unit244.pas.39: MyObject := TTest.Create; 00457E57 B201 mov dl,$01 00457E59 A1547C4500 mov eax,[$00457c54] 00457E5E E8C5B9FAFF call TObject.Create Unit244.pas.40: Method := MyObject.MyMethod; 00457E63 89442404 mov [esp+$04],eax 00457E67 C70424947E4500 mov [esp],$00457e94 Unit244.pas.41: pMethod := @Method; 00457E6E 8B0424 mov eax,[esp] Unit244.pas.42: Method2 := pMethod^; 00457E71 8B10 mov edx,[eax] 00457E73 89542408 mov [esp+$08],edx 00457E77 8B5004 mov edx,[eax+$04] 00457E7A 8954240C mov [esp+$0c],edx Unit244.pas.44: Method; 00457E7E 8B442404 mov eax,[esp+$04] 00457E82 FF1424 call dword ptr [esp] Unit244.pas.45: Method2; 00457E85 8B44240C mov eax,[esp+$0c] 00457E89 FF542408 call dword ptr [esp+$08] Unit244.pas.46: end; 00457E8D 83C410 add esp,$10 00457E90 C3 ret 00457E91 8D4000 lea eax,[eax+$00] Unit244.pas.52: ShowMessage('aa'); 00457E94 B8A87E4500 mov eax,$00457ea8 00457E99 E89644FDFF call ShowMessage | Der Delphicode dazu: Delphi-Quelltext 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53:
| { ... } procedure TForm244.Button1Click(Sender: TObject); type TMethod = procedure of object; var Method: TMethod; Method2: TMethod; pMethod: ^TMethod; MyObject: TTest; begin MyObject := TTest.Create; Method := MyObject.MyMethod; pMethod := @Method; Method2 := pMethod^;
Method; Method2; end;
procedure TTest.MyMethod; begin ShowMessage('aa'); end; | // Ich sehe schon die Antwort, aber ich poste es einfach einmal trotzdem inkl. Ergänzung:
Mit @@ dann sieht der Code so aus: Delphi-Quelltext 9: 10: 11:
| { ... } 00457E67 C70424907E4500 mov [esp],$00457e90 Unit244.pas.41: pMethod := @@Method; 00457E6E 8BC4 mov eax,esp | Man sieht also, dass jetzt direkt der Wert aus esp genommen wird statt dem Wert an der referenzierten Speicherstelle.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 12.05.10 12:32
Jap. Der Delphi-Compiler vergisst bei der Zuweisung TROTZ dem angegebenen @ einmal die Adresse zu bilden. Manchmal kann einem die Compiler-Magic wirklich auf den Keks gehen.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
|