当前位置:  开发笔记 > 编程语言 > 正文

将合格的非静态成员函数作为函数指针传递

如何解决《将合格的非静态成员函数作为函数指针传递》经验,为你挑选了2个好方法。

我在外部库中有一个函数,我无法使用以下签名进行更改:

void registerResizeCallback(void (*)(int, int))

我想传递一个成员函数作为回调,因为我的回调需要修改实例变量.

显然,这是不可能的简单:

registerResizeCallback(&Window::Resize);

所以我不确定如何解决这个问题.



1> Michael Burr..:

正如伊戈尔奥克斯所说,你不能这样做.这个问题的其余部分并不是对你的问题的答案,而是讨论这样的事情应该如何与正确设计的回调API一起使用(看起来你正在使用的那个不是).

大多数设计良好的回调接口允许您提供" void *"或其他方式来获取回调中的上下文.在C++中使用它的一种常用方法是在void *context参数中传递一个对象指针,然后回调函数可以将它强制转换为对象指针并调用成员方法来完成实际工作.你正在使用的回调API没有提供上下文数据太糟糕了.

严格来说,回调必须是extern "C",但使用静态成员方法进行回调很常见,我认为在实践中从来没有问题.(这假设回调API是C接口,这是迄今为止最常见的).

一个例子:

// callback API declaration's

extern "C" {
    typedef unsigned int callback_handle_t;

    typedef void (*callback_fcn_t)( void* context, int data1, int data2);

    callback_handle_t RegisterCallback( callback_fcn_t, void* context);
    void UnregisterCallback( callback_handle_t);
}

// ----------------------------------

// prototype for wrapper function that will receive the callback and 
//  transform it into a method call

extern "C" 
static void doWorkWrapper( void* context, int data1, int data2);


// the class that does the real work

class worker {
public:
    worker() {
        hCallback = RegisterCallback( doWorkWrapper, this);
    }

    ~worker() {
        UnregisterCallback( hCallback);
    }

    void doWork( int data1, int data2) {
        // ... 
    };

private:
    callback_handle_t hCallback;
};

// the wrapper that transforms the callback into a method call
extern "C" 
static void doWorkWrapper( void* context, int data1, int data2)
{
    worker* pWorker = static_cast( context);

    pWorker->doWork( data1, data2);
}



2> Igor Oks..:

检查"[33.2]如何将指针指向成员函数传递给信号处理程序,X事件回调,启动线程/任务的系统调用等?" 在C++ FAQ Lite中:

别.

因为如果没有要调用它的对象,成员函数就没有意义,所以不能直接执行此操作

...

作为现有软件的补丁,使用顶级(非成员)函数作为包装器,该包装器获取通过其他技术获得的对象.

推荐阅读
罗文彬2502852027
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有