Подтвердить что ты не робот

Как получить HMODULE для текущего исполняемого кода?

У меня есть статическая библиотека, которая может быть связана как с .exe, так и с .dll. Во время выполнения я хочу, чтобы мои функции библиотеки получали HMODULE для любой вещи, к которой был привязан статический код библиотеки.

В настоящее время я использую следующий трюк (вдохновленный этот форум):

const HMODULE GetCurrentModule()
{
    MEMORY_BASIC_INFORMATION mbi = {0};
    ::VirtualQuery( GetCurrentModule, &mbi, sizeof(mbi) );

    return reinterpret_cast<HMODULE>(mbi.AllocationBase);
}

Есть ли лучший способ сделать это, что не выглядит настолько взломанным?

(Примечание. Цель этого заключается в загрузке некоторых ресурсов Win32, которые, как я знаю, будут связаны моими пользователями одновременно с моей статической библиотекой.)

4b9b3361

Ответ 1

HMODULE GetCurrentModule()
{ // NB: XP+ solution!
  HMODULE hModule = NULL;
  GetModuleHandleEx(
    GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
    (LPCTSTR)GetCurrentModule,
    &hModule);

  return hModule;
}

Ответ 2

__ImageBase - это сгенерированный компоновщиком символ, который является заголовком DOS модуля (только MSVC). Из этого вы можете привести его адрес к HINSTANCE или HMODULE. Так что это удобнее, чем проходить через API.

Так что вам просто нужно сделать это:

EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)

С https://devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483

Ответ 3

Я бы посмотрел GetModuleHandleEx() с помощью флага GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS. Похоже, вы можете изменить свой GetCurrentModule(), чтобы вызвать эту процедуру вместо VirtualQuery(), и передать адрес GetCurrentModule() в качестве аргумента lpModuleName.

ETA:

const HMODULE GetCurrentModule()
{
    DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS;
    HMODULE hm = 0;
    ::GetModuleHandleEx( flags, reinterpret_cast<LPCTSTR>( GetCurrentModule ), &hm );   
    return hm;
}

Я не пробовал, но думаю, что будет делать то, что вы хотите.

Ответ 4

HMODULE - это HINSTANCE - базовый адрес модуля. Итак, я посмотрю, как это работает. Но если все, что вам нужно, это HMODULE исполняемого файла, почему бы не перечислить все HMODULE в этом процессе (EnumProcessModules). Один из них будет содержать ваш .lib.

Ограничение, которое я вижу, заключается в том, что вы не знаете, из какой DLL или EXE ваш .lib. Возможно, вам захочется сравнить HMODULE (базовые адреса) с _ReturnAddress, который вы получите из своего .lib. Ваш .lib будет принадлежать наивысшему HMODLUE меньше, чем ваш _ReturnAddress