2015-08-28 187 views
6

我在delphi XE8中很新。我有以下代码是从我的delphi版本6,我想在delphi XE8运行它。不兼容的类型:'PAnsiChar'和'PWideChar'

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' 

我搜索无处不在的解决方案,但我只是不能解决问题。请帮助..谢谢。

+0

由于XE8支持Unicode,因此PChar与PWideChar类似。解决你的问题申报src:PAnsiChar。不过,你可能还有更多要做。我建议阅读MarcoCantú关于Unicode的白皮书:http://edn.embarcadero.com/article/38980 –

回答

8

在Delphi 2007及更早版本中,PCharPAnsiChar的别名。在Delphi 2009及更高版本中,PCharPWideChar的别名。所以通过改变编译器你改变了代码的含义。

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

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

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

+0

另一种似曾相识。 –

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
    甲指针的8位的Windows(ANSI)字符的空终止字符串。
    此类型在WINNT.H声明如下:
    typedef CHAR *LPSTR;


关系到你的代码的问题是,每个函数的参数lpMultiByteStrPAnsiChar和你传递作为参数的PChar
PCharPAnsiChar的别名德尔福6并且代表在德尔福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's solution