我正在将我的应用程序转换为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获取完整字符串?
答案 0 :(得分:32)
我这里没有Delphi 2009,所以我无法检查它。但也许你必须尝试:
s := PAnsiChar(AnsiString(Application.ExeName));
正如gabr已经指出的那样,这不是一个很好的做法,只有你100%肯定才能使用它。该字符串仅包含直接映射到ANSI范围的字符。
这就是为什么你应该收到警告,因为你要将Unicode转换为ANSI。
答案 1 :(得分:4)
使用String
:
RawByteString
类型
s: RawByteString;
s := LoadSomeRegularString(usually a string type);
PAnsiChar(s) <<< all fine.
答案 2 :(得分:1)
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参数,所以我需要转换unicode字符串。有没有其他替代方法可以先显式转换为AnsiString?
答案 3 :(得分:0)
WideCharToMultiByte可以帮到你。
答案 4 :(得分:0)
我遇到了完全相同的问题。 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;
答案 5 :(得分:-1)
我觉得你有点不对劲。 每个Win32 API函数都有一个unicode对应项,如果它需要一个字符串。 尝试 MapAndLoadW 而不是 MapAndLoad ......