【问题标题】:Map C++ member function to C callback将 C++ 成员函数映射到 C 回调
【发布时间】:2016-08-08 13:48:29
【问题描述】:

在一个 C++ 项目中,我使用 C 库来访问一些硬件。 C-Bindings 包括回调以通知某些输入引脚上的更改。 回调函数如下所示: void callback(char port, uint8_t interrupt_mask, uint8_t value_mask, void *user_data)

在我的实现中,我有一个 SensorController 类,它有一个应该接收回调的成员函数。成员函数看起来像这样void SensorController::pinChanged(char port, uint8_t interrupt_mask, uint8_t value_mask, void *user_data)

现在我想知道,避免将 pinChanged 函数设为静态以便能够将函数分配给回调的最简洁方法是什么?

【问题讨论】:

    标签: c++ c callback


    【解决方案1】:

    使用user_data 指针返回指向拥有回调的类的指针。例如。

    void MyCallback(char port, uint8_t interrupt_mask, uint8_t value_mask, void *user_data)
    {
        static_cast<Example *>(user_data)->Callback(port, interrupt_mask, value_mask);
    }
    
    class Example
    {
    public:
    
        Example()
        {
            //setup callback here - i dont know what library you're using but you should be able to pass a this pointer as user_data
            init_lib(fictionalparameter1, fictionalparameter2, this);
        }
    
    private:
    
         void   Callback(char port, uint8_t interrupt_mask, uint8_t value_mask)
         {
             //callback handler here...
         }
    
         friend void MyCallback(char port, uint8_t interrupt_mask, uint8_t value_mask, void *user_data);
    };
    

    【讨论】:

    • 是的,完全正确。这就是提供用户上下文指针参数的全部意义。
    • 你应该使用 static_cast(reinterpret_cast 是实现定义的)。
    【解决方案2】:

    接收回调的函数只能是:

    1. 普通函数
    2. 静态函数

    为什么不能是成员类函数?

    这都是关于指针的。指向普通函数或静态函数的指针是指向内存的地址。 指向成员类函数的指针是一个偏移量 - 应该添加到对象指针 (this) 以访问该方法。 [参见 jv110 注释]

    在 C++ 中,成员函数有一个隐式参数,它指向 对象(成员函数内的 this 指针)。正常 C 函数可以被认为具有不同的调用约定 从成员函数,所以他们的指针的类型 (指向成员函数的指针与指向函数的指针)是不同的,并且 不相容。 C++ 引入了一种新类型的指针,称为 指向成员的指针,只能通过提供对象来调用。 https://isocpp.org/wiki/faq/pointers-to-members#addr-of-memfn

    您可以在回调中使用 user_data 来访问 user1320881 所说的类成员方法。

    【讨论】:

    • 不,只有指向 non-function 成员的指针是偏移量。成员函数不是真正的成员,这是对内存的巨大浪费。它们就像静态函数,但它们需要一个隐式的“this”参数
    猜你喜欢
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2015-05-07
    • 1970-01-01
    • 1970-01-01
    • 2013-10-12
    相关资源
    最近更新 更多