问题
I'm converting my applications to Delphi 2009 and faced an intriguing issue with some calls that need to convert a string (wide) to AnsiString.
Here's an example to demonstrate the issue I'm having:
var
s: PAnsiChar;
...
s := PAnsiChar(Application.ExeName);
With Delphi 2007 and previous versions, s := PChar(Application.ExeName) would return the application exe path.
with Delphi 2009, s := PAnsiChar(Application.ExeName) returns only 'E'.
My guess is that's because I'm converting a unicode string to an ansi string but how can I convert it so that a PAnsiChar gets the full string?
回答1:
I have no Delphi 2009 here, so I can't check it. But maybe you have to try:
s := PAnsiChar(AnsiString(Application.ExeName));
As gabr already pointed, this is not a very good practice, and you will only use it if you are 100% sure. The string only contains characters that have a direct mapping to the ANSI range.
That's why you should get a warning because you are converting Unicode to ANSI.
回答2:
Instead of using type String
, use RawByteString
:
s: RawByteString;
s := LoadSomeRegularString(usually a string type);
PAnsiChar(s) <<< all fine.
回答3:
Gamecat explicit conversion works. I'm explaining the problem in more detail below so that perhaps someone can point to a better solution.
I'm using the following function to retrieve the application compilation date:
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 requires a PAnsiChar for the ImageName Parameter so I need to convert the unicode string. Is there any other alternative as to explicitly convert to AnsiString first?
回答4:
I had the exact same problem. The PAnsiChar
only points to the first character. I wrote the following function to handle the old functionality.
// 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;
回答5:
WideCharToMultiByte could help you.
回答6:
I think You are a bit off. Every Win32 API function has a unicode counterpart, if it is expecting a string. Try MapAndLoadW instead of MapAndLoad...
来源:https://stackoverflow.com/questions/283759/convert-string-to-pansichar-in-delphi-2009