不兼容的类型:' PAnsiChar'和' PWideChar'

时间:2015-08-28 07:56:17

标签: delphi delphi-xe8

我是delphi XE8的新手。我有以下代码来自我的delphi版本6,我想在delphi XE8中运行它。

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'

我到处寻找解决方案,但我无法解决问题。请帮忙..谢谢。

2 个答案:

答案 0 :(得分:11)

在Delphi 2007及更早版本中,PCharPAnsiChar的别名。在Delphi 2009及更高版本中,PCharPWideChar的别名。因此,通过更改编译器,您可以更改代码的含义。

您只需将PChar替换为PAnsiChar即可解决此问题,代码将具有原始含义。

在现代Unicode Delphi中,使用string(别名UnicodeString)代替COM WideString会更自然。您还可以使用许多库例程中的一个来执行UTF-8转换。

你前面肯定会遇到其他问题。我建议你阅读Marco Cantù's whitepaper on Unicode in Delphi作为下一步行动。

答案 1 :(得分:2)

来自MDSN:

  • MultiByteToWideChar function

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

    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
    );
    
  • 来自Windows Data Types

      

    LPCSTR
      指向由8位Windows( ANSI )字符组成的以空字符结尾的常量字符串的指针   此类型在WinNT.h中声明如下:
      typedef __nullterminated CONST CHAR *LPCSTR;   

       LPSTR
      指向以null结尾的8位Windows( ANSI )字符串的指针   此类型在WinNT.h中声明如下:
      typedef CHAR *LPSTR;

与您的代码相关的问题是每个函数的参数lpMultiByteStr都是PAnsiChar,并且您正在传递PChar作为参数。
PChar Delphi 6 PAnsiChar的别名,代表 Delphi XE8 中的PWideChar

  • 您可以在第8行解决此问题,声明您的功能(并相应地调用它),如下所示:
    function UTF8ToStringLen(const src: PAnsiChar; const Len: Cardinal): WideString;

  • 要解决第25行的问题,请更改功能声明,如:
    function StringToUTF8Len(const src: PAnsiChar; const Len: Cardinal): string;
    和&#34; 臭名昭着的&# 34;行:
    bsiz := WideCharToMultiByte(CP_UTF8, 0, PWideChar(Temp), -1, PAnsiChar(Result), bsiz, nil, nil);

在每种情况下都适用David Heffernan's solution