這是如何工作的?將LONG投射到函數指針?
我看着這個教程從here:
WNDPROC fWndProc =(WNDPROC)GetWindowLong(Msg.hwnd,GWL_WNDPROC);
從msdn它解釋GetWindowLong返回一個被定義爲long的LONG。這使我困惑,因爲它被轉換成函數指針(WNDPROC)。
將long轉換爲函數指針會發生什麼?他們是完全不同的東西。函數指針甚至在long函數甚至不是函數時如何工作?
這是如何工作的?將LONG投射到函數指針?
我看着這個教程從here:
WNDPROC fWndProc =(WNDPROC)GetWindowLong(Msg.hwnd,GWL_WNDPROC);
從msdn它解釋GetWindowLong返回一個被定義爲long的LONG。這使我困惑,因爲它被轉換成函數指針(WNDPROC)。
將long轉換爲函數指針會發生什麼?他們是完全不同的東西。函數指針甚至在long函數甚至不是函數時如何工作?
指針只是變量的地址;所以它是用整數表示的。
標準說uintptr_t
和intptr_t
是具有指針
#include <stdint.h>
int a;
int *pa = &a;
uintptr_t addr_of_a = (uintpt_t)pa;
在32位系統,sizeof(uintptr_t)
sizeof(int *)
= = 4
兼容。在64位系統中,它們是8
。
GetWindowLong
函數用於32位系統,所以其返回值的類型是LONG
,它是4個字節。
然而,在64位系統中,指針的大小是8個字節。所以微軟棄用GetWindowLong
,你應該使用GetWindowLongPtr
和LONG_PTR
。
// the type of the return value of GetWindowLongPtr is LONG_PTR. So this code is safe and portable.
WNDPROC fWndProc = (WNDPROC)GetWindowLongPtr(Msg.hwnd, GWLP_WNDPROC);
如果我說function_ptr = foo; foo是一個地址,還是foo保存一個值作爲function_ptr使用的地址? – user2893243
@ user2893243是的。 – ikh
@ user2893243眼見爲實。試試這個:'#include
在32位Windows上,LONG是一個32位值,與地址大小相同。 @Chris是對的,它起始於一個函數指針,它被轉換爲一個long類型,然後將它作爲函數指針進行轉換。
如果你看看MSDN的筆記,你會注意到GetWindowLongPtr()
已經取代了原來的電話。它返回一個LONG_PTR,這是Microsoft聲明長度與當前進程體系結構上指針大小相同的方式。基本上,它將是32位處理器的32位地址,而64位處理器則是64位處理器。
它假定你運行在一個系統上,在一個函數的所有可能的地址之間存在一個雙射,並且一個長子的所有非陷阱表示的子集。
換句話說,只要至少有儘可能多的LONG值與WNDPROC值一樣多,那麼這可以工作。
通常,編譯器只會將WNDPROC中的位鏟入GetWindowLong內的LONG的內存(或寄存器)中,然後將它們鏟回到您顯示的行的WNDPROC中。
這樣看:它作爲一個函數指針開始,被賦值爲'LONG'作爲返回值,然後被轉換回函數指針。 – chris
您可以合法地在指針和C中的等效長度整數之間來回轉換。但是,不能保證能夠工作,除了'null'指針。 –