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

为何GetProcAddress无法定位QueryInterruptTime函数?

为何WinAPI的GetProcAddress无法找到QueryInterruptTime函数?

你检查了12个相关时间函数,GetProcAddress能找到其余所有函数,唯独找不到QueryInterruptTime,函数列表如下:

GetSystemTime
GetSystemTimeAdjustment
NtQuerySystemTime <<该列表中唯一不在kernel32.dll的函数
SetSystemTime
GetLocalTime
SetLocalTime
GetSystemTimeAsFileTime
GetSystemTimes
GetTickCount
GetTickCount64
QueryPerformanceCounter
QueryInterruptTime

测试代码:

#define _WIN32_WINNT 0x0601 // this line makes no difference
#include <windows.h>
#include <string>
#include <iostream>
#include <realtimeapiset.h>

int main()
{
    HMODULE hModule = GetModuleHandle("kernel32.dll"); // NtQuerySystemTime needs ntdll.dll instead
    FARPROC pFunc = GetProcAddress(hModule, "QueryInterruptTime");
    DWORD errorMessageID = GetLastError();
    LPSTR messageBuffer = nullptr;
    size_t size = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                                NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
    std::string message(messageBuffer, size);
    message = std::string("getLastError ") + std::to_string(errorMessageID) + ": " + message;

    // Free the buffer.
    LocalFree(messageBuffer);
    std::cout << message << std::endl;
    ULONGLONG interruptTime;
    QueryInterruptTime(&interruptTime);
    std::cout << interruptTime << std::endl;
}

编译命令:

g++ repro.cpp -lmincore
a.exe

输出内容:

getLastError 127: The specified procedure could not be found.
161477110141

替换为其他任意函数时,输出变为:

getLastError 0: The operation completed successfully.
(...)

更新:将GetModuleHandle("kernel32.dll")替换为GetModuleHandle("kernelbase.dll")后问题解决,疑问:微软官方文档中说明QueryInterruptTime位于kernel32.dll的内容是否过时或有误?


原因分析

  1. 函数实际导出位置
    QueryInterruptTime实际从kernelbase.dll导出,而非kernel32.dll。现代Windows系统中,微软将大量核心API的实现从kernel32迁移到kernelbase,kernel32更多作为API转发层存在,但并非所有函数都在kernel32中保留导出项,QueryInterruptTime就是其中之一。

  2. 直接调用成功的原因
    你编译时链接了mincore.lib,该库包含QueryInterruptTime的正确导入信息,会自动指向kernelbase.dll中的实现,因此直接调用函数时能正常执行;但手动用GetProcAddress指定kernel32.dll查找时,自然找不到该函数的导出。

  3. 文档表述的简化
    微软官方文档会简化表述,将kernelbase.dll中的API归到kernel32的文档下——因为kernel32是开发者传统认知中的标准系统库入口,文档不会刻意强调每个函数的实际导出模块。这种表述并非错误,而是出于易用性的简化,通过标准头文件和库链接时无需关心底层模块差异,但手动用GetProcAddress查找时必须指定正确模块。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 03:21:10