27

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

4

6 に答える 6

40

ここには Delphi 2009 がないため、確認できません。しかし、多分あなたは試してみる必要があります:

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

gabr が既に指摘したように、これはあまり良い方法ではなく、100% 確実な場合にのみ使用します。文字列には、ANSI 範囲に直接マッピングされる文字のみが含まれます。

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

于 2008-11-12T12:19:27.030 に答える
5

Stringtypeを使用する代わりに、次を使用しRawByteStringます。

s: RawByteString;

s := LoadSomeRegularString(usually a string type);

PAnsiChar(s) <<< all fine.
于 2010-02-25T20:20:16.743 に答える
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 は ImageName パラメータに PAnsiChar を必要とするため、Unicode 文字列を変換する必要があります。最初に AnsiString に明示的に変換する他の方法はありますか?

于 2008-11-12T13:10:00.190 に答える
0

WideCharToMultiByteが役に立ちます。

于 2008-11-12T12:37:12.500 に答える
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;
于 2009-03-05T13:20:21.053 に答える
-2

あなたは少しずれていると思います。すべての Win32 API 関数には、文字列が必要な場合、対応する Unicode があります。MapAndLoadの代わりにMapAndLoadWを試してください...

于 2009-04-20T11:34:44.930 に答える