Преобразование строки в PAnsiChar в Delphi 2009
Я конвертирую свои приложения в Delphi 2009 и сталкиваюсь с интригующей проблемой с некоторыми вызовами, которым необходимо преобразовать строку (широко) в AnsiString.
Вот пример, чтобы продемонстрировать, что у меня есть проблема:
var
s: PAnsiChar;
...
s := PAnsiChar(Application.ExeName);
В Delphi 2007 и предыдущих версиях s: = PChar (Application.ExeName) вернет путь EXE-приложения.
с Delphi 2009, s: = PAnsiChar (Application.ExeName) возвращает только "E".
Я предполагаю, что, поскольку я преобразовываю строку unicode в строку ansi, но как ее преобразовать, чтобы PAnsiChar получил полную строку?
Ответы
Ответ 1
У меня нет Delphi 2009 здесь, поэтому я не могу его проверить. Но, возможно, вам стоит попробовать:
s := PAnsiChar(AnsiString(Application.ExeName));
Как уже указывал gabr, это не очень хорошая практика, и вы будете использовать ее только в том случае, если вы на 100% уверены. Строка содержит только символы, которые имеют прямое сопоставление с диапазоном ANSI.
Вот почему вы должны получить предупреждение, потому что вы конвертируете Unicode в ANSI.
Ответ 2
Вместо использования типа String
используйте RawByteString
:
s: RawByteString;
s := LoadSomeRegularString(usually a string type);
PAnsiChar(s) <<< all fine.
Ответ 3
Работа с явным преобразованием 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?
Ответ 4
У меня была такая же проблема. PAnsiChar
указывает только на первый символ. Я написал следующую функцию для обработки старых функций.
// 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;
Ответ 5
WideCharToMultiByte может вам помочь.
Ответ 6
Я думаю, что ты немного ушел.
Каждая функция Win32 API имеет юникодную копию, если она ожидает строку.
Попробуйте MapAndLoadW вместо MapAndLoad...