喫茶XRAYトップページ

[スレッド全体
]

[12026] PAnsiCharをStrPCopy関数で使用返信 削除
2018/7/11 (水) 06:27:25 Mr.XRAY
Unicode 版の Delphi で PAnsiChar 型の文字列を StrPCopy 関数で使用する
場合は,次のように,uses に AnsiStrings を追加して明示的に AnsiStrings を
記述しみてください.

implementation

uses
  AnsiStrings;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  LPAnsiChar  : PAnsiChar;
begin
  LPAnsiChar := AllocMem(200);
  try
    AnsiStrings.StrPCopy(LPAnsiChar, '日本語 ABC 文字列');
    Memo1.Lines.Add(string(LPAnsiChar));
  finally
    FreeMem(LPAnsiChar);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  LAnsiString : AnsiString;
  LPAnsiChar  : PAnsiChar;
begin
  LAnsiString := '日本語 ABC 文字列';
  LPAnsiChar  := AllocMem(Length(LAnsiString) + 1);
  try
    AnsiStrings.StrPCopy(LPAnsiChar, LAnsiString);
    Memo1.Lines.Add(string(LPAnsiChar));
  finally
    FreeMem(LPAnsiChar);
  end;
end;



[12032] Re:PAnsiCharをStrPCopy関数で使用返信 削除
2018/7/11 (水) 11:58:59 Mr.XRAY
> AnsiStrings を追加して明示的に AnsiStrings を

Move 関数を使ってしまう手もあります.
Move 関数を使用する場合は uses に AnsiStrings は不要です.

※ Length(Ansi文字変数) はバイト数を返します.

procedure TForm1.Button3Click(Sender: TObject);
var
  LAnsiString : AnsiString;
  LPAnsiChar  : PAnsiChar;
begin
  LAnsiString := '日本語 ABC 文字列';
  LPAnsiChar  := AllocMem(Length(LAnsiString) + 1);
  try
    Move(LAnsiString[1], LPAnsiChar^, Length(LAnsiString));
    Memo1.Lines.Add(string(LPAnsiChar));
  finally
    FreeMem(LPAnsiChar);
  end;
end;


[12037] 末尾がWの関数と末尾がAの関数返信 削除
2018/7/12 (木) 06:23:17 Mr.XRAY
Windows API の関数の中には名前が同じで,末尾が W と A のものがあること
があります.
末尾が W の関数は Unicode 版で A は Ansi 版です.
Delphi 2007 以前の非ユニコード版 (Ansi 版) の Delphi で末尾に W も A もない
関数を使用すると自動的に末尾が A の関数が実行されます.
Delphi 2009 以降のユニード版の Delphi で末尾 W も A もない関数を使用すると
自動的に末尾が W の関数が実行されます.

Delphi 2009 以降の Delphi で,引数の型が PChar (PWideChar) に PAnsiChar の
変数を渡すと,

「E2010 'PWideChar' と 'PAnsiChar' には互換性がありません」

というエラーになります.その逆も同じです.
以下はこのことを確認するコードです.
動作確認は Windows 7 U64(SP1) + Delphi XE5(UP2) Pro VCL-32 です.

[02-01_使用する Windows API の関数名を決める]
http://mrxray.on.coocan.jp/Delphi/plSamples/480_GetFullExePath.htm#02-01


function HogeHoge(Arg1: PWideChar): Boolean;
begin
  Form1.Memo1.Lines.Add(Arg1);
  Result := True;
end;

//=============================================================================
//  E2010 'PWideChar' と 'PAnsiChar' には互換性がありません
//  のエラーが発生する例
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
 LPAnsiChar : PAnsiChar;
begin
  Form1.Memo1.Lines.Clear;
  LPAnsiChar := '日本語 ABC 文字列';
  HogeHoge(LPAnsiChar);
end;

//=============================================================================
//  こういうキャストは無効
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
 LPAnsiChar : PAnsiChar;
begin
  Form1.Memo1.Lines.Clear;
  LPAnsiChar := '日本語 ABC 文字列';

  HogeHoge(PWideChar(LPAnsiChar));
  HogeHoge(PChar(LPAnsiChar));
end;

//=============================================================================
//  一度String型でキャストすればPCharでキャスト可能
//  Windows API の関数では実際には末尾が W または A の関数を使用する
//=============================================================================
procedure TForm1.Button3Click(Sender: TObject);
var
 LPAnsiChar : PAnsiChar;
begin
  Form1.Memo1.Lines.Clear;
  LPAnsiChar := '日本語 ABC 文字列';

  HogeHoge(PWideChar(string(LPAnsiChar)));
end;



[12047] Ansi->Unicode->Ansi変換返信 削除
2018/7/13 (金) 20:26:03 Mr.XRAY
> //=============================================================================
> //  一度String型でキャストすればPCharでキャスト可能
> //  Windows API の関数では実際には末尾が W または A の関数を使用する
> //=============================================================================
> procedure TForm1.Button3Click(Sender: TObject);
> var
>  LPAnsiChar : PAnsiChar;
> begin
>   Form1.Memo1.Lines.Clear;
>   LPAnsiChar := '日本語 ABC 文字列';
>
>   HogeHoge(PWideChar(string(LPAnsiChar)));
> end;



ただし,以下のことも考慮する必要があります.

[Ansi->Unicode->Ansi変換をやっちゃ駄目ってどういう事?]
https://ht-deko.com/tech013.html#tech039_20


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82