Delphi Embarcadero XE:String 和 PAnsiChar 出现大量警告

发布于 2024-11-13 11:45:41 字数 481 浏览 2 评论 0原文

我正在尝试从 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

定格我的天空 2024-11-20 11:45:41

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

procedure SendMail( ADestinataire,ASubject : AnsiString);

,您可以

procedure SendMail( ADestinataire,ASubject : String);

在调用 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

procedure SendMail( ADestinataire,ASubject : AnsiString);

or better you can use

procedure SendMail( ADestinataire,ASubject : String);

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.

小梨窩很甜 2024-11-20 11:45:41

只要写:

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

如果您有一个字符串,即一个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);

Just write

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

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 to PAnsiChar. PAnsiChar is a pointer to a sequence of non-Unicode characters. Indeed, a cast to a PSomethingChar 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 to PWideChar.

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 write AnsiString(ADestinataire). Then you cast to a ANSI (non-Unicode) PAnsiChar:

Res := MAPIResolveName(Session, Application.Handle,
  PANsiChar(AnsiString(ADestinataire)), MAPI_LOGON_UI, 0, PRecip);
抽个烟儿 2024-11-20 11:45:41

从 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

晨曦慕雪 2024-11-20 11:45:41

退一步来说:

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

String 曾经是 AnsiString 的别名,这意味着如果您使用 PAnsiChar<,它恰好可以工作。 /code> (即使您应该使用 PChar)。

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

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

ADestinataire: String
PAnsiChar(ADestinataire)

To step back a moment:

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

String used to be an alias for AnsiString, which means it happened to work if you used PAnsiChar (even though you should have used PChar).

Now string is an alias for UnicodeString, which means using PAnsiChar (which was always wrong) is now really wrong.

Knowing this you can solve the question:

ADestinataire: String
PAnsiChar(ADestinataire)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文