[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