首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Delphi11.2: CreateWindowEx在x64上线程失败

Delphi11.2: CreateWindowEx在x64上线程失败
EN

Stack Overflow用户
提问于 2022-11-20 12:44:45
回答 1查看 132关注 0票数 2

我使用彼得·下面的PBThreadedSplashForm在应用程序启动期间显示一个启动窗口。

这个组件工作了10年,但是,自从我的Delphi升级到11.2,我就可以在CreateWindowEx上得到一个AV。

这只发生在Win64平台上,在Win32上的问题上。

有谁知道是什么原因造成的?

EN

Stack Overflow用户

发布于 2022-11-20 12:56:34

由于编译器和链接器中新的默认ASLR设置,这是11.2中出现的许多问题之一。

在非常快速地浏览了源代码之后,我看到了以下内容:

代码语言:javascript
运行
复制
SetWindowLong( wnd, GWL_WNDPROC, Integer( thread.FCallstub ));

thread.FCallstub被定义为Pointer

正如本人所料的。

你看,指针是原生大小的,所以在32位应用程序中,指针是32位宽,而在64位应用程序中,指针是64位宽。

在32位世界中,指针值临时保存在Integer中是非常常见的,这是因为32位指针适合32位Integer

但是在64位应用程序中,这是一个明显的错误,因为64位指针不适合32位Integer。这就像拿5362417812这样的电话号码,把它截短到17812,希望它还能“工作”。

当然,通常情况下,这会导致诸如AVs和内存损坏之类的错误。

然而,直到最近,64位Delphi应用程序中的指针“偶然”没有使用它的32位(所以可能是$0000000000A3BE41,因此将指针截断到$00A3BE41中没有任何效果)的可能性很大。因此,它似乎大部分时间起作用,但只是偶然的。

现在,Delphi编译器和链接器的最新版本启用了ASLR,从而大大降低了此类事故的可能性。

这是一件好事:如果您的代码中有一个严重的错误,最好是立即发现它,而不是“随机地”访问您的客户。

因此,要解决这个问题,您需要遍历代码,并确保从未将指针存储在32位Integer中。相反,使用本机大小的NativeIntPointerLPARAM或任何语义上合适的东西。

(禁用ASLR也将使其在“许多”情况下再次发生意外,但这是一个非常糟糕的方法。您的软件仍然有一个非常严重的错误,随时都可能出现。)

在您的代码中,也有

代码语言:javascript
运行
复制
Integer( Pchar( FStatusMessage ))
Integer( Pchar( msg ))
票数 8
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74508190

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档