只需将该功能封装在一个类中,例如将其称为 HookManager:
class HookManager {
public:
void registerHook( const std::string &name, std::function<...> hook );
void callHooks( const std::string &name );
...
};
当然,您需要将实际签名放入std::function<...>
并进行相应修改callHooks()
。所以现在在你的测试函数中调用那个钩子管理器:
DWORD TestFunc(int Number)
{
printf("The number is %i", Number);
// Plugin codes here
hookManager.callHooks( "TestFunc" );
return 0; // Return when we have done our job
}
您可能可以使用__func__
那里而不是硬编码函数名称。对于钩子管理器对象,您可能可以使用单例模式或将该对象作为参数传递给需要调用钩子的插件初始化代码和函数。如果您使用单例,则在 DLL 内部:
void TestFuncHook();
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
HookManager &hookManager = HookManager::instance();
hookManager.registerHook( "TestFunc", std::bind( TestFuncHook ) );
...
}
如果钩子函数确实匹配钩子的签名,你可以省略 std::bind。另一种解决方案是要求插件具有一些预定义名称的初始化函数,该函数接受 hookManager 作为参数:
extern "C"
void initializeMyPlugin( HookManager &hookManager )
{
hookManager.registerHook( "TestFunc", std::bind( TestFuncHook ) );
}
现在在您的主应用程序中,当您加载 DLL 时,您会查找初始化函数:
HMODULE module = LoadLibrary( "somelibrary.dll" );
FARPROC proc = GetProcAddress( module, "_initializeMyPlugin" );
if( !proc ) {
// it is not a plugin!
return;
}
typedef void (*InitilizeFuncPtr)( HookManager & );
reinterpret_cast<InitilizeFuncPtr>( proc )( hookManager);