Конвертировать строку в PAnsiChar в Delphi 2009 - PullRequest
21 голосов
/ 12 ноября 2008

Я конвертирую свои приложения в Delphi 2009 и столкнулся с интригующей проблемой, связанной с некоторыми вызовами, которые должны преобразовать строку (всю ширину) в AnsiString.

Вот пример, демонстрирующий мою проблему:

var
  s: PAnsiChar;

...

s := PAnsiChar(Application.ExeName);

В Delphi 2007 и предыдущих версиях s: = PChar (Application.ExeName) возвращает путь к exe-приложению.

с Delphi 2009, s: = PAnsiChar (Application.ExeName) возвращает только «E».

Полагаю, это потому, что я конвертирую строку юникода в строку анси, но как я могу преобразовать ее так, чтобы PAnsiChar получил полную строку?

Ответы [ 6 ]

32 голосов
/ 12 ноября 2008

У меня нет Delphi 2009 здесь, поэтому я не могу это проверить. Но, возможно, вам стоит попробовать:

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

Как уже говорил Габр, это не очень хорошая практика, и вы будете использовать ее, только если уверены на 100%. Строка содержит только символы, которые имеют прямое сопоставление с диапазоном ANSI.

Вот почему вы должны получить предупреждение, потому что вы конвертируете Unicode в ANSI.

4 голосов
/ 25 февраля 2010

Вместо использования типа String используйте RawByteString:

s: RawByteString;

s := LoadSomeRegularString(usually a string type);

PAnsiChar(s) <<< all fine.
1 голос
/ 12 ноября 2008

Gamecat явное преобразование работает. Я объясняю проблему более подробно ниже, чтобы, возможно, кто-то мог указать на лучшее решение.

Я использую следующую функцию для получения даты компиляции приложения:

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 требует PAnsiChar для параметра ImageName, поэтому мне нужно преобразовать строку в юникоде. Есть ли другая альтернатива, чтобы сначала явно преобразовать в AnsiString?

0 голосов
/ 20 апреля 2009

Я думаю, ты немного не в себе. Каждая функция Win32 API имеет аналог Unicode, если она ожидает строку. Попробуйте MapAndLoadW вместо MapAndLoad ...

0 голосов
/ 05 марта 2009

У меня была точно такая же проблема. PAnsiChar указывает только на первый символ. Я написал следующую функцию для обработки старой функциональности.

// This function converts a string to a PAnsiChar
// If the output is not the same, an exception is raised
// Author: nogabel@hotmail.com

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 голосов
/ 12 ноября 2008

WideCharToMultiByte может помочь вам.

...