Delphi Embarcadero XE:使用String和PAnsiChar进行大量警告

时间:2011-06-02 13:27:51

标签: string delphi compiler-warnings delphi-xe

我正在尝试从Delphi 2007迁移到Embarcadero RAD Studio XE。 我收到了很多警告。 它们看起来都像这样:我有一个程序,我声明一个“字符串”:

procedure SendMail( ADestinataire,ASubject : String);

我正试图将Windows API称为:

  Res := MAPIResolveName(Session, Application.Handle,
    PAnsiChar(ADestinataire), MAPI_LOGON_UI, 0, PRecip);

所以警告是:

  

W1044:将字符串转换为PAnsiChar怀疑。

我做错了什么/我应该如何纠正(350警告......)?

非常感谢

4 个答案:

答案 0 :(得分:8)

MAPIResolveName使用LPSTR参数,即Delphi中的PAnsiChar。简单MAPI不支持UTF16字符串(尽管它可以与UTF8字符串一起使用),因此如果你遵守简单的MAPI,你应该使用AnsiStrings,例如

procedure SendMail( ADestinataire,ASubject : AnsiString);

或更好,你可以使用

procedure SendMail( ADestinataire,ASubject : String);

并在调用MAPIResolveName

之前将字符串参数显式转换为AnsiStrings

<强>更新 整个Simple MAPI现已弃用;简单MAPI可以与UTF8字符串一起使用,但它需要在code and registry中进行一些更改。

因此,如果问题是将旧的ANSI简单MAPI快速移植到Unicode Delphi,最好是遵守AnsiStrings。

更坚实的方法是完全放弃简单MAPI并改为使用Extended MAPI

答案 1 :(得分:2)

只需写下

Res := MAPIResolveName(Session, Application.Handle,
  PChar(ADestinataire), MAPI_LOGON_UI, 0, PRecip);

如果您有string,即Unicode字符串,即指向Unicode字符序列的指针,则不应将其强制转换为PAnsiCharPAnsiChar是指向非Unicode字符序列的指针。实际上,对PSomethingChar类型的强制转换只是告诉编译器将解释转换中的东西作为指定类型的指针。它不做任何转换。所以,基本上,现在你撒谎到编译器:你有一个Unicode字符串,并指示编译器将其解释为ANSI(非Unicode)字符串。那很糟糕。

相反,您应该将其强制转换为PWideChar,指向一系列Unicode字符的指针。在Delphi 2009+中,PChar相当于PWideChar

当然,如果你向函数发送一个Unicode字符序列的指针,那么函数最好期望Unicode字符,但我不确定这是MAPIResolveName函数的情况。我怀疑它实际上需要ANSI(即非Unicode)字符。如果是这种情况,则需要将Unicode字符串转换为ANSI(非Unicode)字符串。这很简单,只需写AnsiString(ADestinataire)即可。然后转换为ANSI(非Unicode)PAnsiChar

Res := MAPIResolveName(Session, Application.Handle,
  PANsiChar(AnsiString(ADestinataire)), MAPI_LOGON_UI, 0, PRecip);

答案 2 :(得分:1)

从Delphi 2009开始,字符串数据类型现在实现为Unicode字符串。以前的版本将字符串数据类型实现为Ansi字符串(即每个字符一个字节)。

当我们将应用程序从2007年移植到XE时,这会产生重大影响,这些文章非常有用:

Delphi in a Unicode World(三部分中的第一部分)

Delphi and Unicode

Delphi Unicode Migration for Mere Mortals

答案 3 :(得分:0)

退一步:

When using    use the cast
============  ================
String        PChar
AnsiString    PAnsiChar
WideString    PWideChar

String曾经是AnsiString的别名,这意味着如果您使用PAnsiChar 发生了,即使您应该使用{{} 1}})。

现在 PCharstring的别名,这意味着使用UnicodeString(总是错误的)现在真的错。

知道这一点你可以解决这个问题:

PAnsiChar