Search code examples
delphidelphi-xe6

Incompatible Types PAnsiChar and PWideChar since StrAlloc returns PWideChar with StrAlloc


I know this can be simple but at times Unicode issues bother me lot with too much of considerations.

I have this code:

pcBuffer := StrAlloc(Stream.Size + 1) where pcBuffer is defined as PWideChar

The component wants pcBuffer as PAnsiChar now, so If I do so, I get the error for

StrAlloc- Incompatible Types PAnsiChar and PWideChar

since StrAlloc returns PWideChar

How do I solve this?

Can I simply type cast to PAnsiChar or alloacate it in Unicode way or through GetMem?


Solution

  • In Delphi XE, the SysUtils unit defines the following functions:

    function AnsiStrAlloc(Size: Cardinal): PAnsiChar;
    function WideStrAlloc(Size: Cardinal): PWideChar;
    function StrAlloc(Size: Cardinal): PChar;
    

    You should be calling AnsiStrAlloc to allocate a PAnsiChar. This receives a Size measured in characters. You must account for the null-terminator.

    var
      pcBuffer: PAnsiChar;
    ....
    pcBuffer := AnsiStrAlloc(Stream.Size + 1);
    

    However, these functions should be considered deprecated. They are documented as such in the later versions of Delphi. Instead you should probably use AnsiString and so let the compiler manage lifetime and memory allocation.

    var
      str: AnsiString;
      pcBuffer: PAnsiChar;
    ....
    SetLength(str, Stream.Size);
    pcBuffer := PAnsiChar(str);
    

    The lifetime of the buffer is managed by the compiler as is the case for any Delphi string variable.

    It's quite possible that the code above is not the best way to solve your actual problem. Without seeing more details it's hard to say for sure what the best solution is. The only thing that I'm reasonably confident about is that StrAlloc and friends are not the way forward.