我已经查看了所有类似的问题,但这个具体情况似乎没有出现。
我有一个插件系统,插件接收函数的地址,只要它想要插入一个钩子(这是一个类函数)就可以调用。
插件:
struct plugin {
...
bool (*insert_hook)(hook_data*);
...
};
类:
class manager {
...
private:
InsertHook(hook_data *hook);
...
};
经理中的创建功能:
{
...
typedef bool (manager::*InsertHookFunc)(hook_data*);
InsertHookFunc hook_func = &manager::InsertHook;
// assigning this to the plugin ???
// C2440, cannot convert from 'hook_func' to 'bool (__cdecl *)(hook_data *)'
plugin->insert_hook = hook_func;
...
}
管理员调用插件,如果插件需要插入任何挂钩,则需要调用管理器。
这样做的正确方法是什么?我知道它正常工作(插件被传递给类创建函数的函数指针以请求插件对象),但由于它是一个类函数,我似乎无法赋值它(使用非类函数,这个赋值工作正常。)
我可以创建一个非类函数作为管理器的朋友,但我确信这可以直接完成,我只是想不出来......
答案 0 :(得分:2)
这些类型需要匹配:
typedef bool (manager::*InsertHookFunc)(hook_data*);
bool (*insert_hook)(hook_data*);
直接修复是在manager::
内插入另一个plugin
:
bool (manager::*insert_hook)(hook_data*);
最佳风格可能是将typedef
移到class manager
之外,如下所示:
struct manager; // allow manager to be referenced without its definition
typedef bool (manager::*InsertHookFunc)(hook_data*);
struct plugin {
...
InsertHookFunc insert_hook;
...
};
或者如果插件已经看到manager
的定义,只需执行
manager::InsertHookFunc insert_hook;
在处理复杂类型时, typedef
绝对是你的朋友。
答案 1 :(得分:0)
您尝试使用的功能是不同类的非静态函数(当它将被调用时),这意味着您需要调用它一个类的实例。
因此,对于非静态成员函数的函数指针,你需要传递指向实例的指针。
指针的定义将更改为与InsertHookFunc
相同
您可以将其称为(ptr->*hook_func )(<insert arg here>)
或者,如果您将功能(InsertHook
)设为免费朋友或静态会员,则可以按原样使用,您只需删除在作业中&
。
答案 2 :(得分:0)
你不能让通用函数指针指向非静态成员函数。这是因为所有非静态成员函数都有一个隐含的第一个参数this
。是的,您在函数中使用的this
指针实际上是函数的隐藏参数。
由于您的bool
结构中使用了plugin
等类型,我想您只是希望将C ++代码用作插件。在这种情况下,为什么不简单地使plugin
结构成为插件可以继承的抽象基类?
struct plugin
{
...
virtual bool insert_hook(hook_data*) = 0;
...
};
class manager : public plugin
{
public:
...
bool insert_hook(hook_data*) { ... }
...
};