Ответ 1
HMODULE GetCurrentModule()
{ // NB: XP+ solution!
HMODULE hModule = NULL;
GetModuleHandleEx(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)GetCurrentModule,
&hModule);
return hModule;
}
У меня есть статическая библиотека, которая может быть связана как с .exe
, так и с .dll
. Во время выполнения я хочу, чтобы мои функции библиотеки получали HMODULE
для любой вещи, к которой был привязан статический код библиотеки.
В настоящее время я использую следующий трюк (вдохновленный этот форум):
const HMODULE GetCurrentModule()
{
MEMORY_BASIC_INFORMATION mbi = {0};
::VirtualQuery( GetCurrentModule, &mbi, sizeof(mbi) );
return reinterpret_cast<HMODULE>(mbi.AllocationBase);
}
Есть ли лучший способ сделать это, что не выглядит настолько взломанным?
(Примечание. Цель этого заключается в загрузке некоторых ресурсов Win32, которые, как я знаю, будут связаны моими пользователями одновременно с моей статической библиотекой.)
HMODULE GetCurrentModule()
{ // NB: XP+ solution!
HMODULE hModule = NULL;
GetModuleHandleEx(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)GetCurrentModule,
&hModule);
return hModule;
}
__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
Я бы посмотрел 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;
}
Я не пробовал, но думаю, что будет делать то, что вы хотите.
HMODULE - это HINSTANCE - базовый адрес модуля. Итак, я посмотрю, как это работает. Но если все, что вам нужно, это HMODULE исполняемого файла, почему бы не перечислить все HMODULE в этом процессе (EnumProcessModules). Один из них будет содержать ваш .lib.
Ограничение, которое я вижу, заключается в том, что вы не знаете, из какой DLL или EXE ваш .lib. Возможно, вам захочется сравнить HMODULE (базовые адреса) с _ReturnAddress, который вы получите из своего .lib. Ваш .lib будет принадлежать наивысшему HMODLUE меньше, чем ваш _ReturnAddress