Reputation: 45
Related to the question TVirtualMethodInterceptor.Create doesn't support the class that has overload virtual method. . After the modification of RRUZ's answer I got another problem. How should I call the second overload method "SaveLog(str: string; Args: array of TConst);" . As below codes
type
TConst = array of TVarRec;
TLog = class
public
constructor Create();
procedure SaveLog(str: string); overload; virtual;
procedure SaveLog(str: string; Args: TConst); overload; virtual;
end;
constructor TLog.Create(str: string);
begin
end;
procedure TLog.SaveLog(str: string);
begin
MessageBox(GetFocus(), PChar(str), 'Test Message', MB_OK);
end;
procedure TLog.SaveLog(str: string; Args: TConst);
var
buf: string;
begin
buf:=Format(str, Args);
SaveLog(buf);
end;
procedure MyTest(nID: Integer);
var
ttt: TLog;
vmi: TVirtualMethodInterceptor;
begin
ttt:=TLog.Create();
try
ttt.SaveLog('ID = %d', [nID]);
vmi:=TVirtualMethodInterceptor.Create(ttt.ClassType);
try
//
finally
vmi.Free();
end;
finally
ttt.Free();
end;
end;
The code " ttt.SaveLog('ID = %d', [nID]); " will get compiler error : E2250 There is no overloaded version of 'SaveLog' that can be called with these arguments . How should I do ?
Upvotes: 2
Views: 503
Reputation: 612993
The Args
parameter is a dynamic array. Create and populate a dynamic array and pass that.
Your code fails to compile because you attempt to pass an open array constructor. That would be valid if you had an open array, but you don't. You have a dynamic array.
One useful trick you might use is to define a function that accepts a variant open array and returns a dynamic array. Then you can adapt one to the other inline. The function would be declared like this:
function VariantOpenArrayToDynArray(const Args: array of const): TArray<TVarRec>;
Note that I am preferring to use the generic dynamic array TArray<T>
instead of your TConst
. Doing so has benefits of better type compatibility.
Rudy Velthuis covers this in some detail, and shows how to implement the adapter function in this article: Open array parameters and array of const.
That said, TVarRec
is not designed for explicit use. It's the runtime support for variant open arrays. As Rudy's article demonstrates, it takes a fair bit of explicit memory management once you've left the safe confines of compiler support for variant open arrays. I would not recommend the use of TArray<TVarRec>
.
Instead, I suggest that you use the modern variant type, the type that has been designed for use with new style RTTI. That is TValue
. This variant type has been designed for explicit use and memory management is performed automatically. Use TArray<TValue>
rather than TArray<TVarRec>
.
Upvotes: 1