Search code examples
delphiutf-8libxml2delphi-xe5

Suspicious typecast of RawByteString to PWideChar


I use libxml2 (http://www.xmlsoft.org/) for reading/writing xml-files in my Delphi code. libxml2 uses UTF-8 encoding for all strings.

For example, the function xmlsavefile is defined in libxml2 as

int xmlSaveFile (const char * filename, xmlDocPtr cur)

In the libxml2 Delphi bindings this function is translated to

const LIBXML2_SO = 'libxml2-2.dll';
function xmlSaveFile(const FileName: PChar; cur: xmlDocPtr) : Longint; cdecl; external LIBXML2_SO;

This function can be used as

var FileName : string;
xmlSaveFile(PChar(Utf8Encode(FileName)), doc);

This seems to work without any problems and has been tested with various languages including Chinese. However, I get the compiler warning

Suspicious typecast of RawByteString to PWideChar

As everything works fine I tend to ignore this warning. Nevertheless,

  • Can I get rid of this warning?
  • Do I have to expect any issues?

Solution

  • The Delphi binding that you are using is outdated, likely written before Delphi 2009, when (P)Char was still an alias for (P)AnsiChar. From Delphi 2009 onward, (P)Char is now an alias for (P)WideChar instead. So the compiler warning is correct - you really are typecasting the RawByteString returned by UTF8Encode(), which is an AnsiChar-based string, to a PWideChar instead of to a PAnsiChar.

    You need to update the binding (or get an updated version, or find a different binding, that has already made the update) to use PAnsiChar explicitly everywhere that libxml2 uses char* strings, eg:

    function xmlSaveFile(const FileName: PAnsiChar; cur: xmlDocPtr) : Longint; cdecl; external LIBXML2_SO;
    

    And then update your code to match:

    var FileName : string;
    xmlSaveFile(PAnsiChar(UTF8Encode(FileName)), doc);
    
    var FileName : string;
    xmlSaveFile(PAnsiChar(UTF8String(FileName)), doc);
    
    var FileName : UTF8String;
    xmlSaveFile(PAnsiChar(FileName), doc);