Как вызвать функцию GetTickCount () kernel32.dll, используя LoadLibrary (..) в C ++ - PullRequest
1 голос
/ 02 июля 2011

Я ищу функцию для получения времени в миллисекундах на машине с Windows. По сути, я хочу вызвать эту функцию WinAPI GetTickCount (), но я застрял на «использовать LoadLibrary (...) и вызвать функцию GetTickCount ()» часть ..

Я искал все форумы и гуглил его, но везде люди использовали неполные коды, которые не компилируются. Может кто-нибудь написать короткий пример программы для загрузки kernel32.dll и вызова GetTickCount () для отображения времени в миллисекундах?

Пожалуйста, напишите код, который компилируется!

Ответы [ 4 ]

5 голосов
/ 02 июля 2011

Самое первое, что вы должны сделать, это объявить тип указателя функции, который совместим с экспортируемой функцией. Правильное понимание этого является критически важным фактором, который может привести к неприятностям. Посмотрите внимательно на объявление функции, чтобы получить это:

 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, экспорт может быть экспортирован с начальным подчеркиванием, постфиксом "@nn" или искаженным именем, если вы не объявили функцию с extern "C" и использовали компилятор C ++. Чтобы увидеть настоящее имя, используйте Dumpbin.exe / exports в вашей DLL. Также обратите внимание, что GetProcAddress использует const char *, в отличие от остальной части Windows API, которая использует строки Unicode. Нет префикса L в строковом литерале.

Тогда вы называете это, это просто:

DWORD tick = pfnGetTickCount();

Если вы неправильно определили объявление типа указателя на функцию, вы можете потерпеть крах вашей программы с помощью AV, получить странные результаты функции или несбалансированный стек.

1 голос
/ 02 июля 2011

Вы не можете загрузить 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 голосов
/ 02 июля 2011

[kernel32.dll] загружается в каждый процесс, потому что он обеспечивает функцию ExitProcess

Все, что вам нужно сделать, это включить <windows.h> и вызвать GetTickCount.

Ура & hth.,

0 голосов
/ 02 июля 2011

Вам не нужно. Kernel32.dll загружается в каждый процесс x86 в Windows. Вам нужно только включить заголовок, чтобы он работал - компилятор загрузит его для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...