Delphi Embarcadero XE:String 和 PAnsiChar 出现大量警告
我正在尝试从 Delphi 2007 迁移到 Embarcadero RAD Studio XE。 我收到大量警告。 它们看起来都是这样的: 我有一个声明“String”的过程:
procedure SendMail( ADestinataire,ASubject : String);
我正在尝试调用 Windows API,例如:
Res := MAPIResolveName(Session, Application.Handle,
PAnsiChar(ADestinataire), MAPI_LOGON_UI, 0, PRecip);
所以警告是:
W1044:将字符串转换为 PAnsiChar 可疑。
我做错了什么/我应该如何纠正这个问题(350 个警告......)?
非常感谢
I'm trying to migrate from Delphi 2007 to Embarcadero RAD Studio XE.
I'm getting tons of warnings.
They all look like this: I have a procedure where I declare a "String":
procedure SendMail( ADestinataire,ASubject : String);
And I'm trying to call Windows API like:
Res := MAPIResolveName(Session, Application.Handle,
PAnsiChar(ADestinataire), MAPI_LOGON_UI, 0, PRecip);
So the warnings are:
W1044: Transtyping string into PAnsiChar suspect.
What am I doing wrong / how should I correct this (350 warnings...)?
Thank you very much
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
MAPIResolveName 使用 LPSTR 参数,即德尔福中的 PAnsiChar。简单 MAPI 不支持 UTF16 字符串(尽管它可以与 UTF8 字符串一起使用),因此,如果您坚持使用简单 MAPI,则应该使用 AnsiStrings,例如
,您可以
在调用 MAPIResolveName 之前使用字符串参数并将其显式转换为
AnsiStrings >更新
整个简单 MAPI 现已弃用;简单的 MAPI 可以与 UTF8 字符串一起使用,但需要对 代码和注册表。
因此,如果问题是将旧的 ANSI Simple MAPI 快速移植到 Unicode Delphi,最好是坚持 AnsiStrings。
更可靠的方法是完全放弃简单 MAPI 并使用 扩展 MAPI 代替。
MAPIResolveName uses LPSTR parameter, which is PAnsiChar in Delphi. Simple MAPI does not support UTF16 strings (though it can be used with UTF8 strings), so if you adhere to simple MAPI you should use AnsiStrings, for example
or better you can use
and explicitly convert string parameters to AnsiStrings prior to calling MAPIResolveName
Update
The whole Simple MAPI is now deprecated; Simple MAPI can be used with UTF8 strings, but it requires some changes in code and registry.
So if the question is about quick porting old ANSI Simple MAPI to Unicode Delphi, the best is to adhere to AnsiStrings.
A more solid approach is to abandon Simple MAPI completely and use Extended MAPI instead.
只要写:
如果您有一个
字符串
,即一个Unicode字符串,即指向Unicode字符序列的指针,则不应将其转换为PAnsiChar
。PAnsiChar
是指向非 Unicode 字符序列的指针。事实上,转换为 PSomethingChar 类型只是告诉编译器将转换中的内容解释为指定类型的指针。它不做任何转换。所以,基本上,现在你对编译器撒谎:你有一个 Unicode 字符串,并指示编译器将其解释为 ANSI(非 Unicode)字符串。那很糟糕。相反,您应该将其转换为
PWideChar
,即指向 Unicode 字符序列的指针。在 Delphi 2009+ 中,PChar
相当于PWideChar
。当然,如果您向函数发送指向 Unicode 字符序列的指针,则该函数最好期望 Unicode 字符,但我不确定
MAPIResolveName
函数是否属于这种情况。我怀疑它实际上需要 ANSI(即非 Unicode)字符。如果是这种情况,您需要将 Unicode 字符串转换为 ANSI(非 Unicode)字符串。这很简单,只需编写AnsiString(ADestinataire)
即可。然后转换为 ANSI(非 Unicode)PAnsiChar
:Just write
If you have a
string
, that is, a Unicode string, that is, a pointer to a sequence of Unicode characters, you shouldn't cast it toPAnsiChar
.PAnsiChar
is a pointer to a sequence of non-Unicode characters. Indeed, a cast to aPSomethingChar
type simply tells the compiler to interpret the thing inside the cast as a pointer of the specified type. It doesn't do any conversion. So, basically, right now you lie to the compiler: You have a Unicode string and instructs the compiler to interpret it as an ANSI (non-Unicode) string. That's bad.Instead, you should cast it to
PWideChar
, a pointer to a sequence of Unicode characters. In Delphi 2009+,PChar
is equivalent toPWideChar
.Of course, if you send a pointer to a sequence of Unicode characters to the function, then the function had better expect Unicode characters, but I am not sure if this is the case of the
MAPIResolveName
function. I suspect that it actually requires ANSI (that is, non-Unicode) characters. If this is the case, you need to convert the Unicode string to an ANSI (non-Unicode) string. This is easy, just writeAnsiString(ADestinataire)
. Then you cast to a ANSI (non-Unicode)PAnsiChar
:从 Delphi 2009 开始,字符串数据类型现在作为 Unicode 字符串实现。以前的版本将字符串数据类型实现为 Ansi 字符串(即每个字符一个字节)。
当我们将应用程序从 2007 年移植到 XE 时,这产生了重大影响,这些文章非常有帮助:
Delphi in a Unicode世界(三部分中的第一部分)
Delphi 和 Unicode
面向普通人的 Delphi Unicode 迁移
Starting with Delphi 2009, the string data type is now implemented as a Unicode string. Previous versions implemented the string data type as an Ansi string (i.e. one byte per character).
This had significant implications when we ported our apps from 2007 to XE, and these article were very helpful:
Delphi in a Unicode World (first of three parts)
Delphi and Unicode
Delphi Unicode Migration for Mere Mortals
退一步来说:
String
曾经是AnsiString
的别名,这意味着如果您使用PAnsiChar<,它恰好可以工作。 /code> (即使您应该使用
PChar
)。现在
string
是UnicodeString
的别名,这意味着现在使用PAnsiChar
(总是错误的)真的错了。知道了这一点就可以解决这个问题了:
To step back a moment:
String
used to be an alias forAnsiString
, which means it happened to work if you usedPAnsiChar
(even though you should have usedPChar
).Now
string
is an alias forUnicodeString
, which means usingPAnsiChar
(which was always wrong) is now really wrong.Knowing this you can solve the question: