[gelöst]of object
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Ich brauch doch die Objektreferenz überhaupt nicht. Ich seh keine Notwendigkeit in diesem Fall. In Delphi gibts auch ne Methode um diese zu umgehn nur funktioniert diese beim fpc nicht.
So, theo damit ist wohl bewieen das meine Fragestellung so schlecht nicht war. Pluto hats verstanden. Er hat zwar keine Ahnung wovon er spricht aber anscheinend hat er verstanden was ich will. Und Pluto, bitte halt dich mal an mein Motto.
So, theo damit ist wohl bewieen das meine Fragestellung so schlecht nicht war. Pluto hats verstanden. Er hat zwar keine Ahnung wovon er spricht aber anscheinend hat er verstanden was ich will. Und Pluto, bitte halt dich mal an mein Motto.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Was genau ist ein Event ?!?!?!? (Bitte keine Mutmaßungen mit Hieb- uns Stichfester Quellenangabe !!!! )pluto hat geschrieben:ganz einfach: ein Event braucht nun mal ein Object
(M.E.: "TEvent" ist nur ein bestimmter Event-Typ. Andere Callbacks (mit viel mehr Parametern) werden auch Event genannt.)
-Michael
Zuletzt geändert von mschnell am Sa 15. Dez 2007, 19:19, insgesamt 1-mal geändert.
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Zur Not kannst Du die Prozedur mit ASM aufrufen und den ersten (den versteckten "Self"-) Parameter 0 setzen. Ist aber auch nicht schönChristian hat geschrieben: Ich brauch doch die Objektreferenz überhaupt nicht. Ich seh keine Notwendigkeit in diesem Fall.

Wie denn ?Christian hat geschrieben:In Delphi gibts auch ne Methode um diese zu umgehn nur funktioniert diese beim fpc nicht.
-Michael
Zuletzt geändert von mschnell am Sa 15. Dez 2007, 23:32, insgesamt 1-mal geändert.
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
In delphi ist der erste Parameter der "of obejct" Parameter dort ist
procedure Test of object;
=
procedure Test(Obj : Pointer);
in Freepascal ist es mit einem record gelöst
TMethod, aus der Classes unit.
Ergo:
procedure Test of object;
=
TMethod{@Test,nil};
Damit ist die Frage beantwortet.
procedure Test of object;
=
procedure Test(Obj : Pointer);
in Freepascal ist es mit einem record gelöst
TMethod, aus der Classes unit.
Ergo:
procedure Test of object;
=
TMethod{@Test,nil};
Damit ist die Frage beantwortet.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Na Klar. Kann man das wechselseitig aufrufen ? (Ich probier's am Montag,)Christian hat geschrieben:In delphi ist der erste Parameter der "of obejct" Parameter dort ist
procedure Test of object;
=
procedure Test(Obj : Pointer);
Verstehe ich nicht, Der "TMethod" Record ist nicht eine "Procedure of Object" (wie "procedure Test(Obj : Pointer)" ), sondern eine Variablein der man eine solche speichern kann. Das gib'r in Delphi (vielleicht nur implizit) auch.Christian hat geschrieben: in Freepascal ist es mit einem record gelöst
TMethod, aus der Classes unit.
Ergo:
procedure Test of object;
=
TMethod{@Test,nil};
-Michael
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Was meinst Du mit "dem Record eine Methode zuweisen ?
In Delphi (so ähnlich wie):
Wenn x (vom Type "TNotifyEent ") so ein Record" ist, wird x hier "eine Methode zugewiesen" (eigentlich wird der Variable die Referenz auf die Methode zugewiesen).
In FP muss man bei manchen Settings "x := @p" schreiben, was dasselbe bedeutet und nur expliziter ausdrückt. Ich glaube es gibt ein setting, wie man das vermeiden kann.
Ich sehe da bisher den Unterschied zwischen Delphi und FP nicht.
-Michael
In Delphi (so ähnlich wie):
Code: Alles auswählen
var
x: TNotifyEvent;
procedure p(sender: TObject); of object;
begin
end;
begin
x := p;
end.
Wenn x (vom Type "TNotifyEent ") so ein Record" ist, wird x hier "eine Methode zugewiesen" (eigentlich wird der Variable die Referenz auf die Methode zugewiesen).
In FP muss man bei manchen Settings "x := @p" schreiben, was dasselbe bedeutet und nur expliziter ausdrückt. Ich glaube es gibt ein setting, wie man das vermeiden kann.
Ich sehe da bisher den Unterschied zwischen Delphi und FP nicht.
-Michael
Das ist aber eine Hackerei, wenn das auf Delphi nicht gleichermassen klappt.Christian hat geschrieben: Damit ist die Frage beantwortet.
Kann schon sein, dass das so geht. Trotzdem ist die Lösung sicher nicht besonders sauber.
Deshalb wäre es mir auch lieber gewesen, wenn du die Frage in einen grösseren Kontext gestellt hättest, um "kompatible" Lösungen zu finden. Das war alles was ich verlangt habe.
P.S. Der Umgekehrte Hack geht auch, ist aber etwas komplizierter (Habe ich bei: http://www.theo.ch/Kylix/Qt3pas.zip" onclick="window.open(this.href);return false; angewendet).
Callbacks zu Objektmethoden umwandeln:
Code: Alles auswählen
type
TCallBackStub = class
private
PtrList: TList;
public
constructor Create;
destructor Destroy; override;
function CreateStub(ObjectPtr: Pointer; MethodPtr: Pointer): Pointer;
procedure DisposeStub(Stub: Pointer);
procedure DisposeAllStubs;
end;
const
AsmPopEDX = $5A;
AsmMovEAX = $B8;
AsmPushEAX = $50;
AsmPushEDX = $52;
AsmJmpShort = $E9;
type
TStub = packed record
PopEDX: Byte;
MovEAX: Byte;
SelfPointer: Pointer;
PushEAX: Byte;
PushEDX: Byte;
JmpShort: Byte;
Displacement: Integer;
end;
constructor TCallBackStub.Create;
begin
PtrList := TList.Create;
end;
procedure TCallBackStub.DisposeAllStubs;
var i: integer;
begin
for i := 0 to PtrList.Count - 1 do Dispose(PtrList[i]);
end;
destructor TCallBackStub.Destroy;
begin
DisposeAllStubs;
PtrList.Free;
end;
function TCallBackStub.CreateStub(ObjectPtr: Pointer; MethodPtr: Pointer): Pointer;
var
Stub: ^TStub;
begin
// Allocate memory for the stub
New(Stub);
// Pop the return address off the stack
Stub^.PopEDX := AsmPopEDX;
// Push the object pointer on the stack
Stub^.MovEAX := AsmMovEAX;
Stub^.SelfPointer := ObjectPtr;
Stub^.PushEAX := AsmPushEAX;
// Push the return address back on the stack
Stub^.PushEDX := AsmPushEDX;
// Jump to the 'real' procedure, the method.
Stub^.JmpShort := AsmJmpShort;
Stub^.Displacement := (Integer(MethodPtr) - Integer(@(Stub^.JmpShort))) -
(SizeOf(Stub^.JmpShort) + SizeOf(Stub^.Displacement));
// Return a pointer to the stub
Result := Stub;
PtrList.Add(Result);
end;
procedure TCallBackStub.DisposeStub(Stub: Pointer);
var i: integer;
begin
i := PtrList.IndexOf(Stub);
if i > -1 then Dispose(PtrList[i])
end;
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Das läuft aber nur auf i386 CPU´s.
Lazarus is auch nicht Delphi, solche inkompatibilitäen sind völlig OK.
Die LCL soll Schnittstellen Kompaibel zur VCl sein, alles was intern abläuft muss und soll gar nicht so sein wie bei Delphi. Damit würde man sich ja noch mehr Ärger aufhandeln wie so schon mit den Schnittstellen.
Lazarus is auch nicht Delphi, solche inkompatibilitäen sind völlig OK.
Die LCL soll Schnittstellen Kompaibel zur VCl sein, alles was intern abläuft muss und soll gar nicht so sein wie bei Delphi. Damit würde man sich ja noch mehr Ärger aufhandeln wie so schon mit den Schnittstellen.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/