将LONG转换为函数指针?

时间:2014-03-29 01:59:11

标签: c++ windows function winapi pointers

这是如何工作的?

我从here查看了本教程:

  

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

msdn开始,它解释了GetWindowLong返回的LONG定义为long。这让我感到困惑,因为它被转换为函数指针(WNDPROC)。

将long转换为函数指针会发生什么?它们是完全不同的东西。当长期不是函数时,函数指针如何工作?

3 个答案:

答案 0 :(得分: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字节。所以microsoft弃用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);

答案 1 :(得分:1)

在32位Windows上, LONG 是32位值,与地址大小相同。 @Chris是对的,它作为一个函数指针开始转换为long,然后将它作为函数指针进行类型转换。

如果您查看来自MSDN的说明,您会注意到GetWindowLongPtr()已取代原始呼叫。它返回 LONG_PTR ,这是Microsoft声明一个与当前流程体系结构上的指针大小相同的long的方式。基本上,它将是32位地址,32位进程,但64位进程为64位。

答案 2 :(得分:1)

它假设您正在一个系统上运行,在该系统中,函数的所有可能地址之间存在双射,以及long的所有非陷阱表示的子集。

换句话说,只要存在至少与WNDPROC值一样多的LONG值,那么这可以起作用。

通常,编译器只会将WNDPROC中的位铲到GetWindowLong中的LONG的内存(或寄存器)中,然后将它们铲回到WNDPROC中以显示您所在的行。