私はアプリケーションをDelphi 2009に変換していて、文字列(ワイド)をAnsiStringに変換する必要があるいくつかの呼び出しで興味深い問題に直面しました。
これが私が抱えている問題を示す例です:
var
s: PAnsiChar;
...
s := PAnsiChar(Application.ExeName);
Delphi 2007以前のバージョンでは、s:= PChar(Application.ExeName)はアプリケーションの実行パスを返します。
delphi 2009では、s:= PAnsiChar(Application.ExeName)は 'E'のみを返します。
私の推測では、Unicode文字列をANSI文字列に変換しているためですが、PAnsiCharが完全な文字列を取得できるように変換するにはどうすればよいですか?
ここにはDelphi 2009がないため、確認できません。しかし、おそらくあなたは試す必要があります:
s := PAnsiChar(AnsiString(Application.ExeName));
Gabrがすでに指摘したように、これはあまり良い習慣ではありません。100%確信している場合にのみ使用します。文字列には、ANSI範囲に直接マッピングされている文字のみが含まれます。
UnicodeをANSIに変換するため、警告が表示されるのはこのためです。
タイプString
を使用する代わりに、RawByteString
を使用します。
s: RawByteString;
s := LoadSomeRegularString(usually a string type);
PAnsiChar(s) <<< all fine.
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は、ImageNameパラメータにPAnsiCharを必要とするため、Unicode文字列を変換する必要があります。最初に明示的にAnsiStringに変換する他の方法はありますか?
私はまったく同じ問題を抱えていました。 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;
WideCharToMultiByte が役立ちます。