2011-07-02 33 views
1

Windowsマシンでミリ秒単位で時間を取得する関数を探しています。基本的に、私はこのWinAPI関数GetTickCount()を呼びたいと思いますが、 "LoadLibrary(...)呼び出しGetTickCount()関数"の部分についています。kernel32.dll関数を呼び出す方法C++でLoadLibrary(..)を使用してGetTickCount()を呼び出す方法

私はすべてのフォーラムを検索しました。人々はコンパイルしない不完全なコードを使用しています。誰でもkernel32.dllを読み込み、GetTickCount()を呼び出して時間をミリ秒で表示する短いサンプルプログラムを書くことができますか?

コンパイルするコードを記述してください!

+0

なぜあなたは 'LoadLibrary'を呼び出すべきだと思いますか? 'kernel32.dll'は既にすべてのWindowsプロセスにロードされています。自分でロードする必要はありません。 –

答えて

1

あなたはkernel32.dllをロードすることはできません、それはすでにすべてのプロセスにロードされています。 Windowsの各バージョンにはGetTickCountが存在するため、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

あなたはそうする必要はありません。 Windows上のすべてのx86プロセスにKernel32.dllが読み込まれます。ヘッダーをインクルードするだけで、コンパイラーによって読み込まれます。

+0

x64プロセスにロードされませんか? – Rushil

+0

@Rushil:別のディレクトリにある 'kernel32.dll'とも呼ばれる別のファイルが64ビットプロセスに読み込まれます。 –

0

ExitProcess関数&hellipを提供するため、[kernel32.dll]はすべてのプロセスでロードされます。

あなたがしなければならないことは、<windows.h>と、GetTickCountです。

乾杯& HTH。、

+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を使用します。また、GetProcAddressは、Unicode文字列を使用するWindows APIの残りの部分とは異なり、const char *を使用します。文字列リテラルにL接頭辞はありません。

は、その後、あなたはそれを呼び出す、それは簡単です:

DWORD tick = pfnGetTickCount(); 

間違った関数ポインタ型の宣言を得たなら、あなたは奇妙な関数の結果または不均衡なスタックを取得し、AVを使ってプログラムをクラッシュすることがあります。

関連する問題