-2


首先,我想说我在这里找到了关于这件事的其他问题,但这一个有点不同

我从插件系统中唯一想要的是插件可以挂钩我的功能
认为我有这个功能:

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 将是"TestFunc",PluginFunc 将是插件中函数的地址。

在搜索互联网时没有运气,我希望我能在这里找到解决方案(可以是任何外部库甚至是想法)

4

1 回答 1

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);
于 2013-10-24T16:40:55.950 回答