最重要的是,我想说我在这里找到了关于这个问题的其他问题,但是这个问题有点不同
我想从插件系统中唯一想要的是插件可以挂钩我的功能 认为我有这个功能:
DWORD TestFunc(int Number)
{
printf("The number is %i", Number);
// Plugin codes here
return 0; // Return when we have done our job
}
我放置// Plugin codes here
的地方我希望我的插件代码在这里,所以它可以使用函数堆栈并在每次函数调用时添加代码来运行
所以插件代码应该有这样的东西
Hook(char* FuncName, LPVOID /* or DWORD */ PluginFunc);
在FuncName上面的samle中将是"TestFunc"
,而PluginFunc将是插件中函数的地址。
没有运气搜索互联网,我希望我能在这里找到解决方案(可以是任何外部库甚至想法)
答案 0 :(得分:1)
只需在类中封装该功能,例如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);