[gelöst]of object

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Christian
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:

Beitrag von Christian »

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.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

mschnell
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

Beitrag von mschnell »

pluto hat geschrieben:ganz einfach: ein Event braucht nun mal ein Object
Was genau ist ein Event ?!?!?!? (Bitte keine Mutmaßungen mit Hieb- uns Stichfester Quellenangabe !!!! )

(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.

mschnell
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

Beitrag von mschnell »

Christian hat geschrieben: Ich brauch doch die Objektreferenz überhaupt nicht. Ich seh keine Notwendigkeit in diesem Fall.
Zur Not kannst Du die Prozedur mit ASM aufrufen und den ersten (den versteckten "Self"-) Parameter 0 setzen. Ist aber auch nicht schön :).
Christian hat geschrieben:In Delphi gibts auch ne Methode um diese zu umgehn nur funktioniert diese beim fpc nicht.
Wie denn ?

-Michael
Zuletzt geändert von mschnell am Sa 15. Dez 2007, 23:32, insgesamt 1-mal geändert.

Christian
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:

Beitrag von Christian »

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.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

mschnell
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

Beitrag von mschnell »

Christian hat geschrieben:In delphi ist der erste Parameter der "of obejct" Parameter dort ist

procedure Test of object;
=
procedure Test(Obj : Pointer);
Na Klar. Kann man das wechselseitig aufrufen ? (Ich probier's am Montag,)
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};
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.

-Michael

Christian
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:

Beitrag von Christian »

In Delphi kann man diesen record aber garantiert keiner Methode zuweisen.
Das geht aber in fpc.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

mschnell
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

Beitrag von mschnell »

Was meinst Du mit "dem Record eine Methode zuweisen ?

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

Christian
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:

Beitrag von Christian »

lies den thread
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Christian hat geschrieben: Damit ist die Frage beantwortet.
Das ist aber eine Hackerei, wenn das auf Delphi nicht gleichermassen klappt.
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;

Christian
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:

Beitrag von Christian »

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.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Antworten