2015-08-28 188 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