Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Incompatible types: 'PAnsiChar' and 'PWideChar' [duplicate]

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.

like image 203
ErenRavenHeart Avatar asked Aug 28 '15 07:08

ErenRavenHeart


2 Answers

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.

like image 128
David Heffernan Avatar answered Sep 22 '22 15:09

David Heffernan


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.

like image 33
fantaghirocco Avatar answered Sep 19 '22 15:09

fantaghirocco