On 19/10/2012 00:20, Benito van der Zander wrote:
type
ITest = interface
end;
TTest = class(TInterfacedObject, ITest)
  a: integer;
end;

var c : TTest;
    i : ITest;
begin
  c := TTest.Create;
  c.a := 42;
  i := c;
  writeln(c.a);
end.


Evaluating "i" only shows <ITEST> = {
<IUNKNOWN> = {},
  }

but what I want to see is something like it prints for "c" (or both together):

<TTEST> = {
<TINTERFACEDOBJECT> = {
<TOBJECT> = {
      _vptr$TOBJECT = $671c10},
    FREFCOUNT = 1,
    REFCOUNT = 1},
  A = 42}


(although I just noticed that ttest((pointer(i)) - 0x20) prints that, but is that reliable?
it will probably break if a class implements multiple interfaces)


My research shows, that the offset is variable (depends on size of class and amount of interfaces). Also it can not be derived, except by disassembling. As for the memory layout, the answer is always do not rely on it. It has gone wrong for others before.


However in gdb there is a way to get the class name (but not the instance)
>info symbol ppointer(i)^
VTBL_UNIT1_TMYCLASS_$_IMYDELEGATE in section .data of B:/tmp/interface/project1.exe
You can see the address has debug info, and it includes the class name.
However since pascal identifiers can have underscores too, extracting the name may not always be simple


As for the data. WARNING: applies only to current fpc(s). May change at any time, even depending on settings, or target CPU... Who knows.....
The variable points to the Virtual message table of the interface.
Disassemble one of the methods:
>disassemble (^ppointer(intfdelegate)^+3)^
Dump of assembler code for function WRPR_UNIT1_TMYCLASS_$_IMYDELEGATE_$_3_$_UNIT1_TMYCLASS_$__DOTHIS$LONGINT:
   0x004287e0 <+0>:  sub    $0xc,%eax
   0x004287e3 <+3>:  jmp    0x428710 <TMYCLASS__DOTHIS>
the first "sub" gives the offset = 12.

So as a human, you can try to find it.
But since nothing of this is reliable, it will not be implemented.

You can ask the fpc team, to add the offset to the data structure, in a way that is guaranteed not to change.


--
_______________________________________________
Lazarus mailing list
[email protected]
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply via email to