亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么不能在64位Delphi中將地址傳遞給嵌套的局部函數?

為什么不能在64位Delphi中將地址傳遞給嵌套的局部函數?

慕雪6442864 2019-10-21 14:39:39
如。自關閉相關問題以來-下面添加了更多示例。下面的簡單代碼(可找到頂級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位編譯器中的另一個函數。


查看完整回答
反對 回復 2019-10-21
?
HUH函數

TA貢獻1836條經驗 獲得超4個贊

事情是我被迫使用'@'運算符,盡管我為回調提供了準確的簽名,因為編譯器破壞了類型系統,因為如果不使用隱藏參數(至少在64位上),它將無法處理局部函數。 。

查看完整回答
反對 回復 2019-10-21
  • 3 回答
  • 0 關注
  • 581 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號