ちょうど私の2セント。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)
同様のステートメントに関連する問題は追跡が難しい場合があることに注意してください。