将 RawByteString 转换为 PWideChar 的可疑类型转换



我使用 libxml2(http://www.xmlsoft.org/( 在我的 Delphi 代码中读取/写入 xml 文件。 libxml2 对所有字符串使用 UTF-8 编码。

例如,函数 xmlsavefile 在 libxml2 中定义为

int xmlSaveFile (const char * filename, xmlDocPtr cur)

在 libxml2 Delphi 绑定中,此函数被转换为

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

此函数可用作

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

这似乎没有任何问题,并且已经过包括中文在内的多种语言的测试。但是,我收到编译器警告

RawByteString 转换为 PWideChar 的可疑类型转换

由于一切正常,我倾向于忽略此警告。不过

  • 我可以摆脱这个警告吗?
  • 我必须期待任何问题吗?

错误在于导入函数的声明:

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

此函数接受 8 位 UTF8 编码的文件名。这可以从 C 代码中看出,该代码将文件名参数声明为const char *

将代码更改为:

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

然后通过:

PAnsiChar(Utf8Encode(FileName))

您使用的 Delphi 绑定已经过时,可能是在 Delphi 2009 之前编写的,当时(P)Char仍然是(P)AnsiChar的别名。 从德尔福2009年开始,(P)Char现在是(P)WideChar的别名。 所以编译器警告是正确的 - 你实际上是将UTF8Encode()返回的RawByteString类型转换为AnsiChar,这是一个基于 的字符串,到PWideChar而不是PAnsiChar

您需要更新绑定(或获取更新版本,或查找已进行更新的其他绑定(以在libxml2使用char*字符串的所有位置显式使用PAnsiChar,例如:

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

然后更新代码以匹配:

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

最新更新