GetModuleHandleW: найти уже загруженный модуль
GetModuleHandleW ищет модуль, уже загруженный в адресное пространство текущего процесса. Это API Windows, а не часть стандартного C. Успешный вызов возвращает HMODULE; при ошибке результат равен NULL и доступен GetLastError().
Пример для Windows C
#include <windows.h>
#include <stdio.h>
int main(void) {
HMODULE app = GetModuleHandleW(NULL);
if (app == NULL) {
fprintf(stderr, "GetModuleHandleW failed: %lu\n",
(unsigned long)GetLastError());
return 1;
}
printf("Process executable module: %p\n", (void *)app);
return 0;
}Соберите пример компилятором C с Windows SDK. Значение адреса зависит от запуска, фиксированного ожидаемого адреса нет. NULL в аргументе означает EXE, создавший текущий процесс. Вызов из DLL не превращает этот результат в handle вызывающей DLL.
Поиск по имени
HMODULE library = GetModuleHandleW(L"kernel32.dll");Здесь явно выбрана Unicode-версия, поэтому литерал имеет префикс L. Поиск имени регистронезависим. Если несколько загруженных библиотек имеют одинаковое базовое имя, короткое имя неоднозначно; не полагайтесь на случайный результат.
Отличие от LoadLibrary
| Операция | Назначение |
|---|---|
| GetModuleHandleW | Найти уже загруженный модуль без увеличения счётчика ссылок. |
| LoadLibrary / LoadLibraryEx | Загрузить библиотеку или получить собственную ссылку с правилами загрузчика. |
| GetProcAddress | Найти точный экспорт в подходящем DLL handle. |
Не передавайте handle от GetModuleHandle в FreeLibrary: этот вызов не приобрёл отдельную ссылку. Статическая .lib сама по себе не является DLL-модулем, который можно так найти. Модули DLL также не получают отдельное адресное пространство внутри одного процесса.
Многопоточность и срок жизни
Между поиском и использованием другой поток может выгрузить библиотеку. Если вам нужно удерживать модуль, изучите GetModuleHandleEx и выбранные флаги владения. Проверка «handle не NULL» сама по себе не гарантирует, что указатель на экспорт останется действительным.