我想将格式化参数Args
传递给Format函数。
我找到了一些例子,但是我无法找到如何在TVarRec成员中分配字符串常量。使用E2089 Invalid typecast
进行编译时,以下代码失败。
procedure TForm1.Button1Click(Sender: TObject);
var Arguments: array of TVarRec;
begin
SetLength(Arguments, 2);
Arguments[0].VInteger := 111;
Arguments[1].VAnsiString := PAnsiString('Text'); // I want to set this member
ShowMessage(Format('Decimal: %d, String: %s', Arguments));
end;
有人可以建议我如何将字符串(或AnsiString)常量设置为TVarRec成员吗?我正在使用Delphi 2009。
非常感谢
答案 0 :(得分:9)
这似乎适用于XE:
var
Args: array[0..1] of TVarRec;
S: AnsiString;
U: UnicodeString;
begin
S := 'Hello';
U := 'world';
Args[0].VType := vtAnsiString;
Args[0].VAnsiString := Pointer(S);
Args[1].VType := vtUnicodeString;
Args[1].VUnicodeString := Pointer(U);
Writeln(Format('%s, %s!', Args));
end;
答案 1 :(得分:5)
只是我的两分钱。 TOndrej的回答是正确的,但我只是想强调一些观点。评论并不是一个好地方。
请注意,必须在AnsiString
期间引用TVarRec
。
例如,如果您编写一个设置TVarRec
数组的函数,则应确保将函数内创建的AnsiString
临时副本复制到变量中,该变量将保留到所有时间使用TVarRec
数组。否则,您可能会有一些随机访问冲突(不是每次都有,但只有当MM重新分配ansistring
内存时)。
例如,以下代码不正确:
type
TVarRec2 = array[0..1] of TVarRec;
procedure SetVarRec(a,b: integer; var Result: TVarRec2);
begin
Result[0].VType := vtAnsiString;
Result[0].VString := pointer(AnsiString(IntToStr(a)));
Result[1].VType := vtUnicodeString;
Result[1].VString := pointer(UnicodeString(IntToStr(b)));
end;
因为当程序结束时将释放AnsiString
和UnicodeString
临时变量,Results[].VString
仍会指向那些释放的内存......
使用带有一些临时私有字符串的类或记录可能会起到作用:
type
TMyVar2 = record
private
tmpA: AnsiString;
tmpB: UnicodeString;
public
VarRec: TVarRec2;
procedure SetVarRec(a,b: integer);
end;
procedure TMyVar2.SetVarRec(a,b: integer);
begin
VarRec[0].VType := vtAnsiString;
tmpA := AnsiString(IntToStr(a));
VarRec[0].VString := pointer(tmpA);
VarRec[1].VType := vtUnicodeString;
tmpB := UnicodeString(IntToStr(b));
VarRec[1].VString := pointer(tmpB);
end;
当然,在您的课程中,您可能已经有一个课程。在这种情况下,您最好使用方法和一些私有临时字符串。对于多线程安全(即重入)的方法,您应该提供临时字符串作为参数...
我使用此技巧来生成一个有效的TVarData
动态数组,其中包含一些AnsiString
个内容。实际上,TVarData
和TVarRec
都使用这种非引用的指向字符串的指针,这可能会造成混淆。
请注意,涉及pointer(S)
类似陈述的问题可能难以跟踪。
答案 2 :(得分:0)
你必须使用ansistring值的数组,因为你必须使用点
temps: array of AnsiString;
value: array of TVarRec;
...
max_count := 10;
setlength(temps,max_count);
setlength(value,max_count);
for i := 0 to max_count-1 do begin
temps[i] := IntToStr(i);
value[i].VType := vtAnsiString;
value[i].VString := Pointer(temps[i]);
end;
AdoTable.insertrecord(value);