J'ai une bibliothèque statique qui peut être liée à un .exe
ou un .dll
. Au moment de l'exécution, je veux que mes fonctions de bibliothèque obtiennent le HMODULE
pour tout ce dans quoi le code de bibliothèque statique a été lié.
J'utilise actuellement l'astuce suivante (inspirée de ce forum ):
const HMODULE GetCurrentModule()
{
MEMORY_BASIC_INFORMATION mbi = {0};
::VirtualQuery( GetCurrentModule, &mbi, sizeof(mbi) );
return reinterpret_cast<HMODULE>(mbi.AllocationBase);
}
Y a-t-il une meilleure façon de faire cela qui ne semble pas si hacky?
(Remarque: le but de ceci est de charger des ressources Win32 que je sais que mes utilisateurs auront liées en même temps que ma bibliothèque statique.)
HMODULE GetCurrentModule()
{ // NB: XP+ solution!
HMODULE hModule = NULL;
GetModuleHandleEx(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)GetCurrentModule,
&hModule);
return hModule;
}
__ImageBase
est un symbole généré par l'éditeur de liens qui est l'en-tête DOS du module (MSVC uniquement). À partir de cela, vous pouvez convertir son adresse en HINSTANCE
ou HMODULE
. C'est donc plus pratique que de passer par une API.
Il vous suffit donc de faire ceci:
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
De https://devblogs.Microsoft.com/oldnewthing/20041025-00/?p=3748
Je regarderais GetModuleHandleEx()
en utilisant le drapeau GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
. Il semble que vous pouvez modifier votre GetCurrentModule()
pour appeler cette routine au lieu de VirtualQuery()
et passer l'adresse de GetCurrentModule()
comme argument 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;
}
Je ne l'ai pas essayé, mais je pense que ça fera ce que tu veux.