[fpc-devel] comparing methods
Den Jean
Den.Jean at telenet.be
Sun Sep 13 22:02:45 CEST 2009
On Thursday 10 September 2009 16:56:20 Peter Vreman wrote:
> You can use the TMethod record to access the fields:
> writeln(hexstr(tmethod(@c.p).data));
> writeln(hexstr(tmethod(@c.p).code));
> end.
kind of related to this,
In the Qt binding I had to revert to a non type safe method
for signal hooking. Because the compiler does not always see
the difference between a method provide to a procedure
as a parameter and calling the method and giving the
method result as a parameter to the procedure.
So I cannot directly give the hooked procedure as a parameter
to a procedure, I have to do stuff like this
var M : TMethod
TSomeMethodTyp(M):=MyMethod
Hook_Signal(M);
Instead of
Hook_Signal(MyMethod)
The following code shows the problem of
default parameters confusing the compiler:
(compile with or w/o define DEFINE DEFAULT_VALUE.)
program hooks;
{$mode delphi}
{$DEFINE DEFAULT_VALUE}
uses SysUtils,Classes,Types;
{$IFNDEF DEFAULT_VALUE}
type
TMethod_1Param = procedure(Value:integer) of object;
procedure Hook_M_1Param(aMethod: TMethod_1Param);
begin
writeln('Hooked: Method.Code:',HexStr(TMethod(aMethod).Data),'
Method.Data:',HexStr(TMethod(aMethod).Code));
TMethod_1Param(aMethod)(143);
end;
{$ELSE}
type
TMethod_1Param = procedure(Value:integer=0) of object;
procedure Hook_M_1Param(aMethod: TMethod);
begin
writeln('Hooked: Method.Code:',HexStr(aMethod.Data),'
Method.Data:',HexStr(aMethod.Code));
TMethod_1Param(aMethod)(143);
end;
{$ENDIF}
type
TC = class(TObject)
public
F : integer;
constructor Create;
{$IFNDEF DEFAULT_VALUE}
procedure M_1Param(Value:integer);
{$ELSE}
procedure M_1Param(Value:integer=0);
{$ENDIF}
end;
constructor TC.Create;
{$IFDEF DEFAULT_VALUE}
var M : TMethod;
{$ENDIF}
begin
inherited Create;
F:=142;
{$IFNDEF DEFAULT_VALUE}
Hook_M_1Param(M_1Param);
{$ELSE}
TMethod_1Param(M):=M_1Param;
Hook_M_1Param(M);
{$ENDIF}
end;
procedure TC.M_1Param(Value:integer);
begin
writeln('M_1Param called with Value:',Value,' and F is:',F);
end;
var
C : TC;
{$IFDEF DEFAULT_VALUE}
M : TMethod;
{$ENDIF}
begin
C:=TC.Create;
{$IFNDEF DEFAULT_VALUE}
writeln('C.Instance:',HexStr(TMethod(TMethod_1Param(C.M_1Param)).Data));
writeln('C.M_1Param:',HexStr(TMethod(TMethod_1Param(C.M_1Param)).Code));
{$ELSE}
// Uncomment the following lines to have a compiler error.
// Illegal type conversion: "untyped" to "<procedure variable type of
procedure(LongInt="0") of object;Register>
//writeln('C.Instance:',HexStr(TMethod(TMethod_1Param(C.M_1Param)).Data));
//writeln('C.M_1Param:',HexStr(TMethod(TMethod_1Param(C.M_1Param)).Code));
// Trick with MethodType casting a Method variable
TMethod_1Param(M):=C.M_1Param;
writeln('C.Instance:',HexStr(M.Data));
writeln('C.M_1Param:',HexStr(M.Code));
{$ENDIF}
end.
More information about the fpc-devel
mailing list