2

我已经查看了所有类似的问题,但似乎没有出现这种特定情况。

我有一个插件系统,当插件想要插入一个钩子(这是一个类函数)时,它会接收要调用的函数的地址。

插入:

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;
    ...
}

管理器调用插件,如果插件需要插入任何钩子,它需要调用管理器。

这样做的正确方法是什么?我知道它可以正常工作(插件被传递给类创建函数的函数指针以请求插件对象),但由于它是类函数(使用非类函数,这个任务工作正常)。

我可以创建一个非类函数作为经理的朋友,但我确信这可以直接完成,我就是想不通......

4

3 回答 3

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在处理复杂类型时绝对是您的朋友。

于 2012-11-23T05:52:13.573 回答
0

您尝试使用的函数是不同类的非静态函数(何时调用),这意味着调用它需要类的实例

因此,要使指向非静态成员函数的函数指针起作用,您还需要将指针传递给实例

指针的定义将更改为与InsertHookFunc 您将其称为相同的(ptr->*hook_func )(<insert arg here>)

或者,如果您将 function( InsertHook)设为免费朋友静态成员,它会照原样工作,您只需删除&作业中的 。

于 2012-11-23T05:37:25.280 回答
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*) { ... }
    ...
};
于 2012-11-23T06:31:58.527 回答