web-dev-qa-db-fra.com

Convertir une chaîne en PAnsiChar dans Delphi 2009

Je convertis mes applications en Delphi 2009 et j'ai rencontré un problème intrigant avec certains appels qui doivent convertir une chaîne (large) en AnsiString.

Voici un exemple pour illustrer le problème que je rencontre:

var
  s: PAnsiChar;

...

s := PAnsiChar(Application.ExeName);

Avec Delphi 2007 et les versions précédentes, s: = PChar (Application.ExeName) renverrait le chemin exe de l'application.

avec Delphi 2009, s: = PAnsiChar (Application.ExeName) renvoie uniquement "E".

Je suppose que c'est parce que je convertis une chaîne unicode en chaîne ansi mais comment puis-je la convertir pour qu'un PAnsiChar obtienne la chaîne complète?

21
smartins

Je n'ai pas de Delphi 2009 ici, donc je ne peux pas le vérifier. Mais vous devez peut-être essayer:

s := PAnsiChar(AnsiString(Application.ExeName));

Comme gabr l'a déjà souligné, ce n'est pas une très bonne pratique, et vous ne l'utiliserez que si vous êtes sûr à 100%. La chaîne contient uniquement des caractères qui ont un mappage direct avec la plage ANSI.

C'est pourquoi vous devriez recevoir un avertissement car vous convertissez Unicode en ANSI.

32
Toon Krijthe

Au lieu d'utiliser le type String, utilisez RawByteString:

s: RawByteString;

s := LoadSomeRegularString(usually a string type);

PAnsiChar(s) <<< all fine.
4
Meka

La conversion explicite de Gamecat fonctionne. J'explique le problème plus en détail ci-dessous afin que quelqu'un puisse peut-être indiquer une meilleure solution.

J'utilise la fonction suivante pour récupérer la date de compilation de l'application:

function LinkerTimeStamp(const FileName: string): TDateTime;
var
  LI: TLoadedImage;
begin
  {$IFDEF UNICODE}
  Win32Check(MapAndLoad(PAnsiChar(AnsiString(FileName)), nil, @LI, False, True));
  {$ELSE}
  Win32Check(MapAndLoad(PChar(FileName), nil, @LI, False, True));
  {$ENDIF}
  Result := LI.FileHeader.FileHeader.TimeDateStamp / SecsPerDay + UnixDateDelta;
  UnMapAndLoad(@LI);
end;

MapAndLoad nécessite un PAnsiChar pour le paramètre ImageName, j'ai donc besoin de convertir la chaîne unicode. Existe-t-il une autre alternative pour convertir explicitement en AnsiString en premier?

1
smartins

J'ai eu exactement le même problème. PAnsiChar pointe uniquement vers le premier caractère. J'ai écrit la fonction suivante pour gérer l'ancienne fonctionnalité.

// This function converts a string to a PAnsiChar
// If the output is not the same, an exception is raised
// Author: [email protected]

function StringToPAnsiChar(stringVar : string) : PAnsiChar;
Var
  AnsString : AnsiString;
  InternalError : Boolean;
begin
  InternalError := false;
  Result := '';
  try
    if stringVar <> '' Then
    begin
       AnsString := AnsiString(StringVar);
       Result := PAnsiChar(PAnsiString(AnsString));
    end;
  Except
    InternalError := true;
  end;
  if InternalError or (String(Result) <> stringVar) then
  begin
    Raise Exception.Create('Conversion from string to PAnsiChar failed!');
  end;
end;
0
Nogabel

WideCharToMultiByte pourrait vous aider.

0
Jamie