Question

Je veux transmettre les arguments de formatage Args dans le Format fonction.J'en ai trouvé quelques exemples, mais je n'arrive pas à savoir comment attribuer une constante de chaîne dans le TVarRec membre.Le code suivant échoue lors de la compilation avec 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;

Quelqu'un peut-il me suggérer comment définir la constante chaîne (ou AnsiString) sur le membre TVarRec ?J'utilise Delphi 2009.

Merci beaucoup

Était-ce utile?

La solution

Cela semble fonctionner sous 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;

Autres conseils

Juste mes deux cents.La réponse de TOndrej est correcte, mais je voulais juste souligner certains points.Et les commentaires ne sont pas un bon endroit pour le faire.

Veuillez noter que le AnsiString doit être référencé à tout moment TVarRec sera utilisé.

Par exemple, si vous écrivez une fonction définissant un tableau de TVarRec, vous devez vous assurer que vous avez fait une copie temporaire du AnsiString créé au sein de la fonction à une variable qui restera jusqu'à tout moment TVarRec tableau est utilisé.Sinon, vous risquez d'avoir une violation d'accès aléatoire (pas à chaque fois, mais seulement lorsque le MM réaffecte le ansistring mémoire).

Par exemple, le code suivant est Incorrect:

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;

Parce que le AnsiString et UnicodeString les variables temporaires seront libérées à la fin de la procédure, et Results[].VString pointera toujours vers la mémoire libérée...

Utiliser une classe ou un enregistrement avec une chaîne privée temporaire peut faire l'affaire :

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;

Bien entendu, dans votre programme, vous pouvez avoir une classe déjà existante.Dans ce cas, vous feriez mieux d'utiliser une méthode et des chaînes temporaires privées.Pour que la méthode soit multi-thread sécurisée (c'est-à-direréentrant), vous devez fournir les chaînes temporaires comme paramètres...

J'utilise cette astuce pour avoir un tableau dynamique valide de TVarData contenant quelques AnsiString contenu dans une classe.En fait, TVarData et TVarRec les deux utilisent un tel pointeur non référencé vers des chaînes, ce qui peut prêter à confusion.

Soyez conscient que les problèmes impliquant pointer(S) des déclarations similaires peuvent être difficiles à suivre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top