如。自关闭相关问题以来-下面添加了更多示例。下面的简单代码(可找到顶级Ie窗口并枚举其子窗口)可以在“ 32位Windows”目标平台上正常运行。早期版本的Delphi也没有问题:procedure TForm1.Button1Click(Sender: TObject); function EnumChildren(hwnd: HWND; lParam: LPARAM): BOOL; stdcall; const Server = 'Internet Explorer_Server'; var ClassName: array[0..24] of Char; begin Assert(IsWindow(hwnd)); // <- Assertion fails with 64-bit GetClassName(hwnd, ClassName, Length(ClassName)); Result := ClassName <> Server; if not Result then PUINT_PTR(lParam)^ := hwnd; end;var Wnd, WndChild: HWND;begin Wnd := FindWindow('IEFrame', nil); // top level IE if Wnd <> 0 then begin WndChild := 0; EnumChildWindows(Wnd, @EnumChildren, UINT_PTR(@WndChild)); if WndChild <> 0 then .. end;我插入了,Assert以指示在使用“ 64位Windows”目标平台时失败的地方。如果我没有嵌套回调,则代码没有问题。我不确定参数传递的错误值只是垃圾,还是由于某些错误的内存地址(调用约定?)引起的。嵌套回调实际上是我一开始不应该做的事情吗?还是这仅仅是我必须忍受的缺陷?
3 回答
30秒到达战场
TA贡献1828条经验 获得超6个赞
该技巧从未得到该语言的正式支持,并且由于32位编译器的实现细节,您到目前为止一直在使用它。该文档很清楚:
嵌套过程和函数(在其他例程中声明的例程)不能用作过程值。
如果我没记错的话,一个额外的隐藏参数将通过指向封闭堆栈框架的指针传递给嵌套函数。如果未引用封闭环境,则在32位代码中将其省略。在64位代码中,总是传递额外的参数。
当然,问题的很大一部分是Windows单元将无类型的过程类型用作其回调参数。如果使用了键入程序,则编译器可能会拒绝您的代码。实际上,我认为这是对您所使用的欺骗绝不合法的信念的证明。对于类型化的回调,即使在32位编译器中,也永远无法使用嵌套过程。
无论如何,最重要的是您不能将嵌套函数作为参数传递给64位编译器中的另一个函数。
HUH函数
TA贡献1836条经验 获得超4个赞
事情是我被迫使用'@'运算符,尽管我为回调提供了准确的签名,因为编译器破坏了类型系统,因为如果不使用隐藏参数(至少在64位上),它将无法处理局部函数。 。
添加回答
举报
0/150
提交
取消