In Delphi, how do I find out the the address of a COM method? I can hardcode the offsets
//0 is the offset of the QueryInterface method
p := TPonterArray(pointer(SomeInterface)^)[0];
but I would prefer to use symbolic names. The folllowing obviously does not work:
var M : TMethod;
...
M := TMethod(SomeInterface.QueryInterface);
Thanks!
You can use the
vmtoffset
assembler directive to get the byte offset of an interface method relative to the start of the interface's method table. Take a look at the implementation of_IntfCast
in System.pas, for example:The first expression adds 0; the second, 8.
You cannot parameterize those expressions, though. They're compile-time constants, so you cannot choose which method you want at run time. You need to have all possible method names represented in advance.
All you really need to hook is
QueryInterface
. Once you have that, you can return whatever proxy object you want that can intercept calls to all the other methods.I don't think Delphi supports that. Hardcoding the offsets is probably the only thing that will work, since the compiler doesn't count interface methods as symbols whose value can be assigned to a function pointer, the way object methods or standalone functions can.
Why are you trying to do this, BTW?
Your code is wrong because an interface reference is not a pointer to an interface method table but a pointer to pointer to an interface method table. That is how Delphi interfaces are implemented on binary level. It is hard to say more and point out to the error in your code because you have not given a code example that can be compiled. Use the following code to convert interface reference to method pointer correctly, the idea was taken from Barry Kelly's demonstration of creating a method pointer from a method reference:
If you prefer symbolic names for MethNo you are better to declare them yourself as offset constants
docwiki.embarcadero.com
Here the code to get the needed method pointer