How to call a kernel32.dll function GetTickCount()

2019-02-15 23:48发布

I am searching for a function to get time in milliseconds on a windows machine. Essentially, I want to call this WinAPI function GetTickCount(), but I'm stuck on "use LoadLibrary(...) n call GetTickCount() function" part..

I searched every forum n googled it but everywhere people have used incomplete codes that don't compile..Can anyone write a short sample program to load kernel32.dll and call GetTickCount() to display the time in milliseconds?

Please write code that compiles!

标签: winapi time
4条回答
Ridiculous、
2楼-- · 2019-02-16 00:34

[kernel32.dll] is loaded in every process, because it provides the ExitProcess function…

All you have to do is include <windows.h> and call GetTickCount.

Cheers & hth.,

查看更多
Bombasti
3楼-- · 2019-02-16 00:41

The very first thing you should do is declare a function pointer type that's compatible with the exported function. Getting this right is critical and the greatest odds for running into trouble. Look carefully at the function declaration to arrive at this:

 typedef DWORD (WINAPI * GetTickCount_t)(void);

Next, use LoadLibrary and GetProcessAddress to obtain the function pointer value. You always have to cast the return value of GPA to the function pointer type. Like this:

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

Failure modes here are the path to the DLL. I didn't have to specify one because kernel32.dll is stored in c:\windows\system32, a directory that's always in the search path. That's generally not the case for your own DLL. Only storing it in the same directory as your main EXE allows you to specify just the DLL file name instead of the full path. Review the docs for SetDllDirectory() for background info.

And the name of the exported function. Again it was easy here, the Windows API functions are exported with undecorated names. That's generally not the case for your own DLL, exports can be exported with a leading underscore, a "@nn" postfix or a mangled name if you didn't declare the function with extern "C" and used the C++ compiler. To see the real name use Dumpbin.exe /exports on your DLL. Also note that GetProcAddress uses a const char*, unlike the rest of the Windows API that uses Unicode strings. No L prefix on the string literal.

Then you call it, that's easy:

DWORD tick = pfnGetTickCount();

If you got the function pointer type declaration wrong then you may crash your program with an AV, get bizarre function results or an imbalanced stack.

查看更多
该账号已被封号
4楼-- · 2019-02-16 00:46

You can't load kernel32.dll, it's already loaded into every process. And GetTickCount exists on every version of Windows, so you don't need GetProcAddress to see if it exists. All you need is:

#include <windows.h>
#include <iostream>

int main(void)
{
    std::cout << GetTickCount() << std::endl;
}

A dynamic load example (since winmm.dll is not preloaded):

#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;
}

I've successfully compiled and run this example using Visual Studio 2010 command prompt, no special compiler or linker options are needed.

查看更多
放我归山
5楼-- · 2019-02-16 00:49

You don't have to. Kernel32.dll is loaded into every x86 process on Windows. You only have to include the header to make it work- the compiler will load it for you.

查看更多
登录 后发表回答