web-dev-qa-db-ja.com

Delphi 2009で文字列をPAnsiCharに変換する

私はアプリケーションを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が完全な文字列を取得できるように変換するにはどうすればよいですか?

21
smartins

ここにはDelphi 2009がないため、確認できません。しかし、おそらくあなたは試す必要があります:

s := PAnsiChar(AnsiString(Application.ExeName));

Gabrがすでに指摘したように、これはあまり良い習慣ではありません。100%確信している場合にのみ使用します。文字列には、ANSI範囲に直接マッピングされている文字のみが含まれます。

UnicodeをANSIに変換するため、警告が表示されるのはこのためです。

32
Toon Krijthe

タイプStringを使用する代わりに、RawByteStringを使用します。

s: RawByteString;

s := LoadSomeRegularString(usually a string type);

PAnsiChar(s) <<< all fine.
4
Meka

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に変換する他の方法はありますか?

1
smartins

私はまったく同じ問題を抱えていました。 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;
0
Nogabel

WideCharToMultiByte が役立ちます。

0
Jamie