Announcement

Collapse
No announcement yet.

Object Methoden als Pointer

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Object Methoden als Pointer

    Hallo Entwickler!<p>Ich benötige für eine Rotine eine Methode als Pointer. Es sollte dann ungefähr so aussehen:<p>Routine(@ObjMethode)<p>Ich weiß, daß man dies besser mit TObject gelöst hätte, aber leider ist die Routine nun mal so. Kann mir jemand helfen?<p>Gruss Andreas

  • #2
    Hi

    Könntest Du das mal genauer spezifizieren ? kleiner Code und warum Du es so brauchst ? Generell ist eine Object-Methode wie ein Event definiert, also ein Record ähnlich TMethod. D.h. es werden ZWEI Zeiger benötigt, einer auf den Code und einer als 1. Parameter Self auf das Object selber.

    Gruß Hage

    Comment


    • #3
      Hi,

      Soweit ich weiß sind Objektmethodenzeiger keine echten Zeiger sondern
      nur ein ein Offset von der VMT (Virtual Method Table) aus.

      Wenn ich z.B. ein API-Callback aufrufe verwende ich eine nicht Objektmehtode und reiche den Aufruf eins zu eins an die Objektmethode weiter.

      zB:

      Type
      TTest = class
      public
      procedure ObjMethod( x : TX );
      end;

      var
      Test : TTest

      procedure Method( x : TX );

      implementation

      procedure Method( x : TX );
      begin
      Test.ObjMethod(x);
      end;

      ...

      Es gibt bestimmt auch bessere Lösungen oder

      Comment


      • #4
        Jo, in Deinem Beispiel gehst Du über eine globale Object Instance variable um dann eine Methode aufzurufen. Das kann fehlerträchtig sein.

        Eine Object-Methode, oder kurz Methode, ist ein record

        <pre>

        type
        TMethod = packed record
        Data: Pointer;
        Code: Pointer;
        end;

        </pre>

        Auch als Event benutzt.

        Um eine Object Methode aufzurufen muß man deren Typ, (static, virtual, dynamic) und dessen Aufrufkonvention unterscheiden (pascal, register, stdcall, cdecl, safecall).<br>

        Eine als static deklarierte Methode wird durch den Compiler zur Compilerungszeit aufgelösst, d.h. der Compiler erzeugt direkt einen CALL zur entsprechenden Codeadresse, hardcoded.

        <pre>

        Self.Free // static Object Methode <br>

        mov eax,self
        call $xxxxxxxxx // Aufruf der static Object Methode<br>
        <br>
        Self.InstanceSize // static class Methode<br>

        mov eax,[eax] // eax = Self.ClassType = type TClass
        call $xxxxxxxxx // Aufruf einer static class Methode<br>
        <br>
        Self.Destroy // virtual object method<br>

        mov eax,self
        mov ecx,[eax] // eax = Self.ClassType = type TClass
        call dword ptr [ecx + vmtDestroy] // aufruf indirekt über die VMT<br>
        <br>

        Self.CallDynMethod(12) // Aufruf einer dynm. methode<br>

        mov eax,self
        mov edx,12 // Index in DMT
        call GetDynaMethod // ermittle dynm. Methode
        mov eax,self
        call ecx

        </pre>

        Fazit, virtuelle Object Methoden werden NICHT über deren VMT Slot aufgerufen, diese dynamische Aufrufkonvention wird nur in dynamischen methoden benutzt, also alle mit dynamic oder message definierten Methoden. Virtuelle Methoden nutzen dagegen indirekte calls über die VMT=virtuelle Methoden Table.
        Deren Auflösung=Indizierung durch den VMT-Slot Offset wird während der Compilierungszeit hardcoded.

        Gruß Hage

        Comment

        Working...
        X