2011-07-02 153 views
1

我搜索功能在Windows機器上毫秒獲得時間。本質上,我想調用這個WinAPI函數GetTickCount(),但我被卡在「使用LoadLibrary(...)n調用GetTickCount()函數」部分..如何調用使用調用LoadLibrary(..)一個kernel32.dll中函數的GetTickCount()在C++

我搜索了每個論壇ñGoogle搜索它,但無處不在人們使用不完整的代碼,不編譯..任何人都可以寫一個簡單的示例程序來加載kernel32.dll並調用GetTickCount()來顯示時間以毫秒爲單位?

請編寫代碼編譯!

+0

爲什麼你認爲你應該調用'LoadLibrary'? 'kernel32.dll'已經加載到每個Windows進程中,你不需要自己加載它。 –

回答

1

不能裝載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命令提示符下成功編譯並運行這個例子,沒有特殊的編譯器或鏈接器選項是必需的。

+0

是的,我明白了。但是,你可以試試如何使用LoadLibrary ..(如果我想加載另一個庫) – Rushil

+0

@Rushil:當然,但我會將你的例子改爲'timeGetTime',因此討論加載庫是有意義的。 –

0

你不需要。 Kernel32.dll被加載到Windows上的每個x86進程中。你只需要包含頭文件就可以工作 - 編譯器會爲你加載它。

+0

它不會被加載到x64過程中嗎? – Rushil

+0

@Rushil:一個不同的文件,也被命名爲'kernel32.dll',但位於不同的目錄中,被加載到64位進程中。 –

0

[KERNEL32.DLL]裝載在每個過程中,因爲它提供了ExitProcess功能&hellip;

所有你需要做的是包括<windows.h>和呼叫GetTickCount

乾杯&心連心,

+0

謝謝你做到了!但是如果我不得不在另一個dll中調用一個函數呢..你能告訴我如何調用LoadLibrary來完成這項工作嗎? – Rushil

4

你應該做的第一件事就是聲明一個函數指針類型與導出功能兼容。如何正確做到這一點至關重要,是造成麻煩的最大可能性。仔細查看函數聲明以達到此目的:

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。另請注意,與使用Unicode字符串的其他Windows API不同,GetProcAddress使用const char *。字符串文字上沒有L前綴。

然後你怎麼稱呼它,這很簡單:

DWORD tick = pfnGetTickCount(); 

如果你有函數指針類型聲明錯誤,那麼你可以用AV你的程序崩潰,得到奇怪的函數結果或不平衡的堆棧。