Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2017-05

How to call virtual StoredProc from PropInfo

2 messages · 1 person ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Ondrej Pokorny

Hello!

For the Lazarus IDE I need to call the stored function from a property.

I was able to get the pointer of a static procedure and call it:

function GetStoredFunction(APropInfo: PPropInfo; AInstance:
TPersistent): CodePointer;
var
   StoredProcType: Byte;
begin
   StoredProcType := ((APropInfo^.PropProcs shr 4) and 3);
   case StoredProcType of
     ptStatic: Result:=APropInfo^.StoredProc; // this is fine
     ptVirtual: Result:=APropInfo^.StoredProc; // this is obviously
wrong - it has to be instance-dependent
   else
     Result:=nil;
   end;
end;
type
   TBoolFunc = function: Boolean of object;
function CallStoredFunction(APropInfo: PPropInfo; AInstance:
TPersistent): Boolean;
var
   Func: TMethod;
   FFunc: TBoolFunc;
begin
   Func.Code := GetStoredFunction(APropInfo, AInstance);
   Func.Data := AInstance;
   FFunc := TBoolFunc(Func);
   Result := FFunc();
end;

But this approach is obviously wrong for virtual stored properties because the StoredProc cannot point to the actual virtual/overridden method.

My question is, how can I call a virtual stored procedure from PropInfo?

+ Test project attached :)

Ondrej

Ondrej Pokorny
to Ondrej Pokorny
Ondrej Pokorny wrote
My question is, how can I call a virtual stored procedure from PropInfo?

Digging through the code, I found it:

function GetStoredFunction(APropInfo: PPropInfo; AInstance:
TPersistent): CodePointer;
var
   StoredProcType: Byte;
   xT: Pointer;
begin
   StoredProcType := ((APropInfo^.PropProcs shr 4) and 3);
   case StoredProcType of
     ptStatic: Result:=APropInfo^.StoredProc; // this is fine
*    ptVirtual: Result :=
PPointer(Pointer(AInstance.ClassType))[{%H-}PtrInt(APropInfo^.StoredProc)
div SizeOf(Pointer)];**
*  end else
     Result:=nil;
   end;
end;

Ondrej