Несовместимые типы: 'PAnsiChar' и 'PWideChar' [дубликат]

этот вопрос уже есть ответ здесь:

Я очень новичок в 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 ответов


в Delphi 2007 и более ранних, PChar псевдоним PAnsiChar. В Delphi 2009 и выше, PChar псевдоним PWideChar. Таким образом, изменяя компилятор, вы изменяете значение кода.

вы можете решить эту проблему, просто заменив PChar с PAnsiChar и код будет иметь свое первоначальное значение.

в современном Unicode Delphi было бы более естественно использовать string (псевдоним UnicodeString) вместо COM WideString. Вы также можете использовать один из многих библиотек процедуры для выполнения преобразования UTF-8.

там, безусловно, будут другие вопросы впереди вас. Я рекомендую вам прочитать белый лист Марко Канту на Unicode в Delphi как твой следующий шаг.


из 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
    );
    
  • С Типы Данных Windows:

    LPCSTR
    Указатель на постоянную строку с нулевым завершением 8-разрядных окон (в ANSI) символов.
    Этот тип объявлен в WinNT.H следующим образом:
    typedef __nullterminated CONST CHAR *LPCSTR;

    LPSTR
    Указатель на строку с нулевым завершением 8-разрядных окон (в ANSI) символов.
    Этот тип объявлен в WinNT.H следующим образом:
    typedef CHAR *LPSTR;


проблемы, связанные с вашим кодом заключается в том, что аргумент lpMultiByteStr каждой функции PAnsiChar и вы проезжаете PChar в качестве параметра.
на PChar - это псевдоним из PAnsiChar на Delphi 6 и стоит PWideChar на Дельфи X Е8.

  • вы можете решить эту проблему в строке #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);

в каждом дело решение Дэвида Хеффернана применяется.