我喜欢Pascal的清晰度,所以请相信下面的代码片段和问题标题是不言自明的:
procedure TForm1.FormClick(Sender: TObject);
const
N = 42; { fnord }
type
{ this structure merely defines memory layout }
TStringStruct = record
NumberOfCharacters: Cardinal;
{ this array supposed to be friendly for the string type }
StringCompatibleArray: array [0..N-1] of Char;
end;
{ actual work is done with pointer to that structure }
PStringStruct = ^TStringStruct;
var
StringStruct: PStringStruct;
S: string;
begin
StringStruct := PopulatedElsewhere;
{ most pleasant code but will copy no more than N characters }
S := StringStruct^.StringCompatibleArray;
{ this construct works but is way too ugly and complex }
SetString(
S,
{ in particular: must reference the array and then typecast to make it work }
{ default $T- state assumed, unfortunately $T+ has global effect and not useful here }
PChar(@StringStruct^.StringCompatibleArray),
StringStruct^.NumberOfCharacters
);
end;
如果有人想要正式提问:我想看看我必须执行哪些选项,最好不要比显示SetString
电话更加模糊。
注意:我知道解除引用运算符对于结构化类型是可选的。
答案 0 :(得分:5)
SetString
是要走的路。如果人们继续对其有用性一无所知,那只是模糊不清。类型转换是必要的,因为有两个重载,并且char数组完全与预期的参数类型(PAnsiChar和PWideChar)不匹配。
这很冗长,但在您的情况下,它很容易包含在您的数据类型的函数中,例如ToString
。正如David在评论中建议的那样,您可以让该函数成为Implicit
运算符,然后自动获得转换:
class operator TStringStruct.Implicit(const Value: TStringStruct): string;
begin
SetString(Result, Value.StringCompatibleArray, Value.NumberOfCharacters);
end;
S := StringStruct^;