2014-03-29 55 views
0

這是如何工作的?將LONG投射到函數指針?

我看着這個教程從here

WNDPROC fWndProc =(WNDPROC)GetWindowLong(Msg.hwnd,GWL_WNDPROC);

msdn它解釋GetWindowLong返回一個被定義爲long的LONG。這使我困惑,因爲它被轉換成函數指針(WNDPROC)。

將long轉換爲函數指針會發生什麼?他們是完全不同的東西。函數指針甚至在long函數甚至不是函數時如何工作?

+1

這樣看:它作爲一個函數指針開始,被賦值爲'LONG'作爲返回值,然後被轉換回函數指針。 – chris

+0

您可以合法地在指針和C中的等效長度整數之間來回轉換。但是,不能保證能夠工作,除了'null'指針。 –

回答

3

指針只是變量的地址;所以它是用整數表示的。

標準說uintptr_tintptr_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,你應該使用GetWindowLongPtrLONG_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); 
+0

如果我說function_ptr = foo; foo是一個地址,還是foo保存一個值作爲function_ptr使用的地址? – user2893243

+0

@ user2893243是的。 – ikh

+0

@ user2893243眼見爲實。試試這個:'#include void foo(){} int main(){printf(「%p \ n」,foo); }' – ikh

1

在32位Windows上,LONG是一個32位值,與地址大小相同。 @Chris是對的,它起始於一個函數指針,它被轉換爲一個long類型,然後將它作爲函數指針進行轉換。

如果你看看MSDN的筆記,你會注意到GetWindowLongPtr()已經取代了原來的電話。它返回一個LONG_PTR,這是Microsoft聲明長度與當前進程體系結構上指針大小相同的方式。基本上,它將是32位處理器的32位地址,而64位處理器則是64位處理器。

1

它假定你運行在一個系統上,在一個函數的所有可能的地址之間存在一個雙射,並且一個長子的所有非陷阱表示的子集。

換句話說,只要至少有儘可能多的LONG值與WNDPROC值一樣多,那麼這可以工作。

通常,編譯器只會將WNDPROC中的位鏟入GetWindowLong內的LONG的內存(或寄存器)中,然後將它們鏟回到您顯示的行的WNDPROC中。