Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 593
Shanand c Avatar asked Dec 02 '25 07:12

Shanand c


2 Answers

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.

like image 81
David Heffernan Avatar answered Dec 04 '25 00:12

David Heffernan


You are calling the StrAlloc() from the SysUtils unit, which allocates a PWideChar.

To allocate a PAnsiChar instead, call the StrAlloc() from the AnsiStrings unit:

uses
  ..., AnsiStrings;

pcBuffer := AnsiStrings.StrAlloc(Stream.Size + 1);
like image 28
Remy Lebeau Avatar answered Dec 04 '25 01:12

Remy Lebeau



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!