如何在C++中使用LoadLibrary(.)调用kernel32.dll函数GetTickCount()



我正在windows机器上搜索一个以毫秒为单位获取时间的函数。本质上,我想调用这个WinAPI函数GetTickCount((,但我被"使用LoadLibrary(…(n调用GetTickCount[((函数"部分卡住了。。

我搜索了每个论坛并在谷歌上搜索了它,但到处都有人使用不完整的代码。。有人能写一个简短的示例程序来加载kernel32.dll并调用GetTickCount((来显示以毫秒为单位的时间吗?

请编写可编译的代码!

您应该做的第一件事就是声明一个与导出函数兼容的函数指针类型。做好这件事至关重要,也是遇到麻烦的最大几率。仔细查看函数声明可以得出以下结果:

 typedef DWORD (WINAPI * GetTickCount_t)(void);

接下来,使用LoadLibrary和GetProcessAddress获取函数指针值。您总是需要将GPA的返回值强制转换为函数指针类型。像这样:

HMODULE hKernel = LoadLibrary(L"kernel32.dll");
assert(hKernel);
GetTickCount_t pfnGetTickCount = (GetTickCount_t)GetProcAddress(hKernel, "GetTickCount");
assert(pfnGetTickCount);

这里的故障模式是DLL的路径。我不必指定一个,因为kernel32.dll存储在c:\windows\system32中,这个目录总是在搜索路径中。您自己的DLL通常不是这样。只有将其存储在与主EXE相同的目录中,才能仅指定DLL文件名,而不是完整路径。查看SetDllDirectory((的文档以了解背景信息。

以及导出函数的名称。这里也很简单,Windows API函数是用未修饰的名称导出的。您自己的DLL通常不是这样,如果您没有用extern"C"声明函数并使用C++编译器,则可以使用前导下划线、"@nn"后缀或损坏的名称导出导出。要查看真实名称,请在DLL上使用Dumpbin.exe/exports。还要注意,GetProcAddress使用const char*,这与使用Unicode字符串的Windows API的其余部分不同。字符串文字上没有L前缀。

然后你称之为,这很简单

DWORD tick = pfnGetTickCount();

如果你的函数指针类型声明错误,那么你可能会用AV破坏你的程序,得到奇怪的函数结果或不平衡的堆栈。

您无法加载kernel32.dll,它已经加载到每个进程中。而且GetTickCount在每个版本的Windows上都存在,所以您不需要GetProcAddress来查看它是否存在。你只需要:

#include <windows.h>
#include <iostream>
int main(void)
{
    std::cout << GetTickCount() << std::endl;
}

动态负载示例(由于winmm.dll未预加载(:

#include <windows.h>
#include <iostream>
int main(void)
{
    HMODULE winmmDLL = LoadLibraryA("winmm.dll");
    if (!winmmDLL) {
        std::cerr << "LoadLibrary failed." << std::endl;
        return 1;
    }
    typedef DWORD (WINAPI *timeGetTime_fn)(void);
    timeGetTime_fn pfnTimeGetTime = (timeGetTime_fn)GetProcAddress(winmmDLL, "timeGetTime");
    if (!pfnTimeGetTime) {
        std::cerr << "GetProcAddress failed." << std::endl;
        return 2;
    }
    std::cout << (*pfnTimeGetTime)() << std::endl;
    return 0;
}

我已经使用Visual Studio 2010命令提示符成功编译并运行了这个示例,不需要特殊的编译器或链接器选项。

您不必这么做。Kernel32.dll加载到Windows上的每个x86进程中。你只需要包含头就可以使它工作——编译器会为你加载它。

[kernel32.dll]在每个进程中都加载,因为它提供了ExitProcess函数…

您所要做的就是包含<windows.h>并调用GetTickCount

干杯&hth。,

最新更新