Incompatible types: 'PAnsiChar' and 'PWideChar'

16,451

Solution 1

In Delphi 2007 and earlier, PChar is an alias for PAnsiChar. In Delphi 2009 and later, PChar is an alias for PWideChar. So by changing compiler you change the meaning of the code.

You can resolve this simply by replacing PChar with PAnsiChar and the code will have its original meaning.

In modern Unicode Delphi it would be more natural to use string (alias of UnicodeString) instead of the COM WideString. You might also use of one the many library routines to perform UTF-8 conversion.

There are surely going to be other issues ahead of you. I recommend that you read Marco Cantù's whitepaper on Unicode in Delphi as your next move.

Solution 2

From the 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
    );
    
  • From Windows Data Types:

    LPCSTR
    A pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters.
    This type is declared in WinNT.h as follows:
    typedef __nullterminated CONST CHAR *LPCSTR;

    LPSTR
    A pointer to a null-terminated string of 8-bit Windows (ANSI) characters.
    This type is declared in WinNT.h as follows:
    typedef CHAR *LPSTR;


The issue related to your code is that the argument lpMultiByteStr of each function is a PAnsiChar and you're passing a PChar as a parameter.
The PChar is an alias of PAnsiChar in Delphi 6 and stands for a PWideChar in Delphi XE8.

  • You can solve this issue at line #8 declaring you function (and calling it accordingly) like this:
    function UTF8ToStringLen(const src: PAnsiChar; const Len: Cardinal): WideString;

  • To solve the issue at line #25, change the function declaration like:
    function StringToUTF8Len(const src: PAnsiChar; const Len: Cardinal): string;
    and the "infamous" line:
    bsiz := WideCharToMultiByte(CP_UTF8, 0, PWideChar(Temp), -1, PAnsiChar(Result), bsiz, nil, nil);

In each case David Heffernan's solution applies.

Share:
16,451
ErenRavenHeart
Author by

ErenRavenHeart

Updated on July 31, 2022

Comments

  • ErenRavenHeart
    ErenRavenHeart almost 2 years

    I am very new in delphi XE8. I have this following code which is from my delphi version 6 and I want to run it in 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;
    

    when I try to run it the error points to line 8 and 25 in the code with an error message saying

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

    I have search everywhere for the solution but I just cant solve the problem. Please help.. Thank you.

  • Rudy Velthuis
    Rudy Velthuis over 8 years
    And another déjà vu.