MinGW下如何不使用-fpermissive将GetProcAddress结果转为函数指针
编译失败原因
不加-fpermissive编译报错的核心原因有两个:
GetProcAddress返回值类型是通用函数指针FARPROC,C++标准不允许签名不匹配的函数指针隐式转换,-fpermissive会把这类类型错误降级为警告才允许原代码通过。- 原代码中
GetModuleHandle(&"ntdll.dll")存在参数类型错误:对字符串字面量取地址得到的是数组指针类型,和函数要求的const char*参数不匹配,同样是被-fpermissive容错放过的非标准写法。
可直接通过标准编译的改写代码
#include <windows.h> // 定义和NtSetTimerResolution签名、调用约定完全匹配的函数指针类型 using PfnNtSetTimerResolution = void (NTAPI*)(ULONG, BOOLEAN, PULONG); PfnNtSetTimerResolution NtSetTimerResolution = nullptr; int main() { HMODULE ntdllHandle = GetModuleHandleA("ntdll.dll"); // 显式做类型转换,匹配目标函数指针类型 NtSetTimerResolution = reinterpret_cast<PfnNtSetTimerResolution>( GetProcAddress(ntdllHandle, "NtSetTimerResolution") ); // 判空后再调用,避免空指针崩溃 if (NtSetTimerResolution) { ULONG currentRes; NtSetTimerResolution(0x1388, TRUE, ¤tRes); } return 0; }
改写说明
- 去掉了原代码中对字符串字面量取地址的错误写法,直接传入符合参数类型要求的字符串常量。
- 使用
reinterpret_cast对GetProcAddress的返回值做显式类型转换,这是C++标准中允许的函数指针转换方式,不需要编译器开启非标准容错选项。 - 函数指针定义时补充了原生NT API要求的
NTAPI(即__stdcall)调用约定,避免32位环境下因调用约定不匹配导致栈损坏崩溃。 - 将原代码中用的C++内置
bool类型、字面量1替换为Windows原生API定义的BOOLEAN类型和TRUE宏,完全匹配系统API的类型约定,消除潜在隐患。 - 增加了函数指针判空逻辑,极端场景下避免空指针访问异常。
内容的提问来源于stack exchange,提问作者anon9000
相关产品推荐
相关产品推荐

