在Delphi 2009中将字符串转换为PAnsiChar

时间:2008-11-12 12:14:10

标签: delphi 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获取完整字符串?

6 个答案:

答案 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 ......