【问题标题】:Class member function as callback using boost::bind and boost::function使用 boost::bind 和 boost::function 作为回调的类成员函数
【发布时间】:2011-01-01 09:03:08
【问题描述】:

我正在为我正在使用的 C 库设置一个成员函数作为回调。 C 库像这样设置回调:

typedef int (*functionPointer_t)(myType1_t*, myType2_t*, myType3_t*);

setCallback(param1, param2, functionPointer, param4)

我想使用 boost::bind (如果可能的话) 来传递函数指针。我希望指向的函数是实例化类的成员,而不是静态成员。例如

Class A {
 public: 
  A();
 protected:
  int myCallback(myType1_t*, myType2_t*, myType3_t*); //aka functionPointer_t
}

这可以使用 boost::bind 和 boost::function 完成吗?根据How can I pass a class member function as a callback?(第三个答案),我似乎可以声明以下内容(在某处,或作为 typedef):

boost::function<int (A*, myType1_t*, myType2_t*, myType3*> myCallbackFunction

然后在 A(ctor)的某处调用该类型的 boost::bind,并将其传递给 C 库调用。

这是可能的,还是我不在基地?非常感谢。

【问题讨论】:

    标签: c++ boost boost-bind boost-function


    【解决方案1】:

    没有。 boost::function 之类的函子类型不会转换为用于 C 回调机制的函数指针。

    但是,大多数 C 回调机制都有某种令牌机制,因此您的回调函数(它是静态的)具有某种上下文信息。您可以使用它来编写一个包装类,将这些标记映射到函子对象,并将执行传递给正确的对象:

    class CallbackManager {
    public:
        typedef boost::function<int (type1*, type2*, type3*)> callback;
    
        static void setCallback(CallbackManager::callback cb)
        {
            void *token = ::setCallback(staticCallback);
            callbacks[token] = callback_I;
        }
    
        static void staticCallback(void* token, type1* a, type2* b, type3* c)
        { return mcallbacks[token](a, b, c); }
    
    private:
        static std::map<void*, callback > callbacks;
    };
    

    【讨论】:

    • setCallback的接口无法更改
    • @jdt141:你能不能滥用setCallback 中的param1, param2, param4 之一来潜入一个令牌,该令牌将通过int (*functionPointer_t)(myType1_t*, myType2_t*, myType3_t*) 返回给你?
    • Emile - 完全错过了您的评论。我相信我可以,但到目前为止,上述方法对我来说效果很好
    【解决方案2】:

    不要使用地图,它会产生运行时开销,并且使用静态地图会导致代码混乱。

    请改用reinterpret_cast

    例如

    // clib.h
    typedef void (*CALLBACK_FUNC)(int code,void *param);
    
    void set_callback( CALLBACK_FUNC, void * param ); 
    
    // a.h
    
    class A {
    public:
        A()
        {
            ::set_callback( &A::static_callback, this);
        }
    private:
        static void static_callback(int code, void * param)
        { 
            A* self = reinterpret_cast<A*>(param);
            self->callback( code );
        }
    
        inline void callback( int code )
        {
            // write you code here.
        }
    };
    

    【讨论】:

      【解决方案3】:

      成员函数的问题在于它们会自动接收指向对象实例的指针作为第一个参数——“this”指针。这就是为什么不能使用成员函数和 C 回调函数的原因。您必须同时拥有对象和函数指针才能使用成员函数。

      【讨论】:

      • 这没有意义。如果这是真的,我将无法将 boost::function 降级为每个 stackoverflow.com/questions/282372/… 的原始指针
      • 其实可以,但是很复杂。这个:A a; a.call(); 相当于这个:A a; A::call(&amp;a); 根据 C++ 规范,我相信。问题是原始函数指针不能带this 指针。
      • 谢谢!这解释了很多。只是过于专注于一种方法,而没有采取明显的路线。
      猜你喜欢
      • 1970-01-01
      • 2012-09-27
      • 2013-09-21
      • 1970-01-01
      • 2015-06-15
      • 2016-03-16
      • 1970-01-01
      • 1970-01-01
      • 2012-04-18
      相关资源
      最近更新 更多