You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MinGW下如何不使用-fpermissive将GetProcAddress结果转为函数指针

编译失败原因

不加-fpermissive编译报错的核心原因有两个:

  1. GetProcAddress 返回值类型是通用函数指针FARPROC,C++标准不允许签名不匹配的函数指针隐式转换,-fpermissive会把这类类型错误降级为警告才允许原代码通过。
  2. 原代码中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, &currentRes);
    }

    return 0;
}
改写说明
  • 去掉了原代码中对字符串字面量取地址的错误写法,直接传入符合参数类型要求的字符串常量。
  • 使用reinterpret_cast对GetProcAddress的返回值做显式类型转换,这是C++标准中允许的函数指针转换方式,不需要编译器开启非标准容错选项。
  • 函数指针定义时补充了原生NT API要求的NTAPI(即__stdcall)调用约定,避免32位环境下因调用约定不匹配导致栈损坏崩溃。
  • 将原代码中用的C++内置bool类型、字面量1替换为Windows原生API定义的BOOLEAN类型和TRUE宏,完全匹配系统API的类型约定,消除潜在隐患。
  • 增加了函数指针判空逻辑,极端场景下避免空指针访问异常。

内容的提问来源于stack exchange,提问作者anon9000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 15:24:25