web-dev-qa-db-ja.com

互換性のないタイプ:「PAnsiChar」および「PWideChar」

私はデルファイXE8で非常に新しいです。私のdelphiバージョン6からの次のコードがあり、delphiXE8で実行したいと思います。

1. function UTF8ToStringLen(const src: PChar; const Len: Cardinal): widestring;
2. var
3.   l: Integer;
4. begin
5.   SetLength(Result, Len);
6.   if Len > 0 then
7.   begin                                             
8.     l := MultiByteToWideChar( CP_UTF8, 0, src, Len, PWChar(Result), Len*SizeOf(WideChar));  <--error
9.     SetLength(Result, l);
10.   end;
11. end;
12. 
13. 
14. function StringToUTF8Len(const src: PChar; const Len: Cardinal): string;
15. var
16.   bsiz: Integer;
17.   Temp: string;
18. begin
19.   bsiz := Len * 3;
20.   SetLength(Temp, bsiz);
21.   if bsiz > 0 then
22.   begin
23.     StringToWideChar(src, PWideChar(Temp), bsiz);
24.     SetLength(Result, bsiz);                
25.     bsiz := WideCharToMultiByte(CP_UTF8, 0, PWideChar(Temp), -1, PChar(Result), bsiz, nil, nil);  <--error
26.     if bsiz > 0 then dec(bsiz);
27.     SetLength(Result, bsiz);
28.   end;
29. end;

実行しようとすると、エラーはコードの8行目と25行目を指し、次のようなエラーメッセージが表示されます。

ERROR MESSAGE: Incompatible types: 'PAnsiChar' and 'PWideChar'

私はどこでも解決策を探していますが、問題を解決することはできません。助けてください..ありがとう。

8
ErenRavenHeart

Delphi 2007以前では、PCharPAnsiCharのエイリアスです。 Delphi 2009以降では、PCharPWideCharのエイリアスです。したがって、コンパイラを変更することで、コードの意味を変更できます。

これは、PCharPAnsiCharに置き換えるだけで解決でき、コードは元の意味を持ちます。

最新のUnicodeDelphiでは、COM stringの代わりにUnicodeStringWideStringのエイリアス)を使用する方が自然です。多くのライブラリルーチンの1つを使用して、UTF-8変換を実行することもできます。

きっとあなたの前に他の問題があるでしょう。次の動きとして DelphiのUnicodeに関するMarcoCantùのホワイトペーパー を読むことをお勧めします。

12
David Heffernan

MDSNから:

  • MultiByteToWideChar関数

    _int MultiByteToWideChar(
     _In_      UINT   CodePage,
     _In_      DWORD  dwFlags,
     _In_      LPCSTR lpMultiByteStr,
     _In_      int    cbMultiByte,
     _Out_opt_ LPWSTR lpWideCharStr,
     _In_      int    cchWideChar
    );
    _
  • WideCharToMultiByte関数

    _int WideCharToMultiByte(
     _In_      UINT    CodePage,
     _In_      DWORD   dwFlags,
     _In_      LPCWSTR lpWideCharStr,
     _In_      int     cchWideChar,
     _Out_opt_ LPSTR   lpMultiByteStr,
     _In_      int     cbMultiByte,
     _In_opt_  LPCSTR  lpDefaultChar,
     _Out_opt_ LPBOOL  lpUsedDefaultChar
    );
    _
  • From Windowsデータ型

    [〜#〜] lpcstr [〜#〜]
    8ビットWindowsのnullで終了する定数文字列へのポインタ([〜#〜] ansi [〜#〜])文字。
    このタイプは、WinNT.hで次のように宣言されています。
    _typedef __nullterminated CONST CHAR *LPCSTR;_

    [〜#〜] lpstr [〜#〜]
    8ビットWindows([〜#〜] ansi [〜#〜])文字のnullで終了する文字列へのポインタ。
    このタイプは、WinNT.hで次のように宣言されています。
    _typedef CHAR *LPSTR;_


コードに関連する問題は、各関数の引数lpMultiByteStrPAnsiCharであり、パラメーターとしてPCharを渡していることです。
PCharは、Delphi 6)のPAnsiCharのエイリアスであり、 PWideChar inDelphi XE8

  • この問題は、次のように関数を宣言する(そしてそれに応じて呼び出す)8行目で解決できます。
    function UTF8ToStringLen(const src: PAnsiChar; const Len: Cardinal): WideString;

  • 25行目の問題を解決するには、次のように関数宣言を変更します。
    function StringToUTF8Len(const src: PAnsiChar; const Len: Cardinal): string;
    および「悪名高い」行:
    bsiz := WideCharToMultiByte(CP_UTF8, 0, PWideChar(Temp), -1, PAnsiChar(Result), bsiz, nil, nil);

いずれの場合も David Heffernanのソリューション が適用されます。

3
fantaghirocco