我正在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。,