为什么不能通过GetProcAddress调用CreateWindow?

开发 前端
在头文件中,您将会看到函数是重定向宏、类似函数的宏、内联函数、内部函数还是适当的导出函数。如果你无法从头文件中弄清楚,你总是可以只编写一个程序来调用你感兴趣的函数,然后查看反汇编以查看实际生成的内容。

有时候,我看到有些人在折腾这样一个问题:
“我想使用 GetProcAddress 来获取 CreateWindow 或者 ExitWindows 的调用地址,但是没有成功。为什么?”

通常,他们当时是在尝试编写平台调用(P/Invoke)相关的代码,因为从底层的角度来看,平台调用是通过 GetProcAddress 来实现的。

问题来了:为什么 GetProcAddress 不能用在这些函数上呢?

原因是:它们(CreateWindow 或 ExitWindows)并非真正的导出函数,如果你查看对应的头文件,则会看到这样的宏定义。

事实上,CreateWindow 是一个双重宏定义,首先它会根据当前是否定义了 UNICODE 来展开为 CreateWindowA 或者 CreateWindowW。然后,这些类似于函数的宏会再次被展开为真正的导出函数 CreateWindowExA 或者 CreateWindowExW。

如果包含 winuser.h 头文件,则所有这些都由编译器自动处理,但如果出于某种原因,您希望为类似函数的宏(如 CreateWindow)使用 GetProcAddress,则必须手动展开宏以查看实际函数是什么,并将该函数名称传递给 GetProcAddress。

上述原理也适用于内联函数。这些函数无法通过 GetProcAddress 获取,因为它们根本不会导出,它们在头文件中作为源代码提供给您调用。

请注意,某些内容是真正的函数还是类似函数的宏(或内联函数)可能取决于您的目标平台。例如,GetWindowLongPtrA 在 64 位 Windows 上是真正的导出函数,但在 32 位 Windows 上,它只是一个解析为 GetWindowLongA 的宏。再举一个例子,Interlocked 系列函数在 x86 版本的 Windows 上是导出函数,但在所有其他 Windows 体系结构上是内联函数。

看起来还挺复杂的,那怎么能弄清楚这一切?方法是:研究头文件。

在头文件中,您将会看到函数是重定向宏、类似函数的宏、内联函数、内部函数还是适当的导出函数。如果你无法从头文件中弄清楚,你总是可以只编写一个程序来调用你感兴趣的函数,然后查看反汇编以查看实际生成的内容。

总结

当有不明白的地方的时候,最好的方法还是去翻阅源文件(头文件)。
请坚信:任何事情(Bug)都是有原因的。

责任编辑:武晓燕 来源: 今日头条
相关推荐

2021-07-30 06:49:40

SSD内存CPU

2022-05-22 21:23:10

前端监控系统

2012-12-18 11:55:38

2019-10-27 23:53:13

PC交换机通信

2022-02-15 07:03:04

start 源码run线程

2013-10-29 10:24:31

程序员漫画

2023-09-14 13:23:42

Llama-2模型参数

2023-10-30 08:51:09

平台管理工程

2011-05-05 17:57:18

软件开发

2017-02-07 20:49:15

2023-01-03 08:07:33

Go字符串指针

2021-07-09 06:00:45

网络钓鱼培训数据泄露

2018-06-04 15:17:10

编程语言中文编程

2009-12-04 13:31:21

PHP全局变量不能生效

2017-12-13 12:33:14

UPS前端漏电

2010-04-27 16:37:59

无线局域网

2011-11-10 10:39:21

苹果Siri

2021-07-19 09:27:42

SSD内存Linux

2015-07-17 11:11:20

虚拟化基础架构服务

2010-10-20 11:06:27

公司
点赞
收藏

51CTO技术栈公众号