Convert string to PAnsiChar in Delphi 2009

蹲街弑〆低调 提交于 2019-12-20 09:47:37

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!