[fpc-devel] How to call virtual StoredProc from PropInfo
    Ondrej Pokorny 
    lazarus at kluug.net
       
    Wed May 17 18:13:45 CEST 2017
    
    
  
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
-------------- next part --------------
program StoredProcVirtual;
uses
  Classes, TypInfo;
type
  TMyObj = class(TPersistent)
  private
    fPropStatic: Integer;
    fPropVirtual: Integer;
    function PropStaticStored: Boolean;
    function PropVirtualStored: Boolean; virtual;
  published
    property PropStatic: Integer read fPropStatic write fPropStatic stored PropStaticStored;
    property PropVirtual: Integer read fPropVirtual write fPropVirtual stored PropVirtualStored;
  end;
{ TMyObj }
function TMyObj.PropStaticStored: Boolean;
begin
  Result := False;
end;
function TMyObj.PropVirtualStored: Boolean;
begin
  Result := False;
end;
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;
var
  X: TMyObj;
  PropStatic, PropVirtual: PPropInfo;
begin
  X := TMyObj.Create;
  PropStatic := TypInfo.GetPropInfo(X, 'PropStatic');
  PropVirtual := TypInfo.GetPropInfo(X, 'PropVirtual');
  Assert(not CallStoredFunction(PropStatic, X)); // OK
  Assert(not CallStoredFunction(PropVirtual, X)); // Error
end.
    
    
More information about the fpc-devel
mailing list