Zitat von
littleDave:
Für Interfaces in den Scripts habe ich mal versucht den Assembler-Code, den Delphi erstellt, versucht zu verstehen. Das Problem ist halt die richtige Zuordnung der Methoden - da habe ich noch kein Konzept für gefunden.
Delphi-Quellcode:
PInterfaceEntry = ^TInterfaceEntry;
TInterfaceEntry = packed record
IID: TGUID;
VTable: Pointer;
IOffset: Integer;
ImplGetter: Integer;
end;
PInterfaceTable = ^TInterfaceTable;
TInterfaceTable = packed record
EntryCount: Integer;
Entries: array[0..9999] of TInterfaceEntry;
end;
TObject:
function GetInterface(const IID: TGUID; out Obj): Boolean;
class function GetInterfaceEntry(const IID: TGUID): PInterfaceEntry;
class function GetInterfaceTable: PInterfaceTable;
Da findestes du schonmal alle Interfaces eines Objektes.
PInterfaceTable
Direkt an der Adresse, wohin der Interfacezeiger zeigt, liegt eine MethodAdressTabelle.
Und die InterfaceMethoden werden einfach über ihren Index aufgerufen.
Delphi-Quellcode:
IInterface = interface
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
Kannst dir ja mal hiervon den
ASM-Code anzeigen lassen:
Delphi-Quellcode:
var Intf: IInterface;
begin
Integer(Intf) := $123;
Intf._AddRef;
_AddRef ist die 2. Methode des Interfaces.
Es gibt auch keine Vorfahren dieses Interfaces ... deren Methoden würden sonst vorher aufgezählt.
Somit hat die Methode die Adresse, welche bei +4 Byte (Index = 1, da 0-basierendes Array) in dieser Tabelle liegt.
Code:
mov eax, Intf
call TMethod(PPointer(Intf)^ + Index)
Delphi-Quellcode:
ITest = Interface(IInterface)
Procedure Test;
end;
PS: Wenn nix angegeben ist, dann ist der Standardvorfahr automatisch IInterface.
.Test läge also bei Index 4 aka +12 Byte (0 bis 3 in IInterface und die 4 in ITest)