使用回调从 C 调用 C++ class 方法

Calling C++ class methods from C using callbacks

我有一个class,Component,它必须与C代码交互。

//// Component.h file   ////
class Component{
public:
    uint8_t getdevice1Value();
    void setdevice1Value(uint8_t value);

    uint8_t getdevice2Value();
    void setdevice2Value(uint8_t uint8_t);
private:
    uint8_t device1Value;
    uint8_t device2Value;
}

class 的对象将在某些 Application.cpp 文件中创建其相关线程时创建:

///////Some function where the Component is used//////
createThread(){
    Component myComponent;  // Scope within the thread
    // Some actions
}

现在是我的 C 代码,它恰好是事件驱动的。在这些功能中,我想 link 我的 Class 方法:

//// device1_event.c file   ////
void command_get_device_value()
{
    // code
    // assign variable  = Component::getdevice1Value() function
    // code
}

void command_set_device_value()
{
    // code
    // call Component::setdevice1Value(variable)  passing some variable
    // code
}

类似于 device1_event.c 文件,我有另一个 device2_event.c,我想在其中将函数调用映射到 getdevice2Valuesetdevice2Value.

我查看了问题 Using a C++ class member function (cannot be static) as a C callback function or also this ,其中 struct 注册了上下文和函数指针。

我在无法动态分配的情况下有一个限制。所以,我不能使用 new 运算符。

现在我有几个关于这些的问题:

  1. callback 概念是否适用于我的情况?
  2. 如果第一个问题是肯定的,那么:
    • 我该如何实施它。我对此有点困惑。我的意思是调用函数需要放在 C 函数中,而且我还需要在创建 Component 实例后注册它们。我该怎么做呢?
    • 如何将回调函数添加到我的 C 文件中?
  3. 一个 struct 被雇佣了。我在哪里声明 'struct'?我确实尝试在 Component.h 文件中声明它,并在 device1_event.c 文件中将其作为 extern 引入。但是我收到 incomplete type 错误。

classC 传递回调的方式是传递两个值:一个指向回调本身的指针,以及一个将传递给回调作为附加参数(例如 qsort_r)。与 C++ 接口时,该不透明值可用作实例指针;你只需要写一个薄的包装器:

class B {
    void my_callback(int arg);
    static void my_callback_wrapper(int arg, void *u) {
        ((B*)u)->my_callback(arg);
    }
};

// or even:
extern "C" void my_callback_wrapper(int arg, void *u) {
    ((B*)u)->my_callback(arg);
}

并将指向包装器的指针与指向对象的指针一起传递给 C 部分。小心在两侧使用完全相同的 class 类型,而不是 base/derived class,例如

请注意,虽然可以获取指向(非静态)方法本身的指针,但在某些编译器(很久以前在 MSVC 上测试过)上,它们具有特殊的调用约定,因此指针不会与 any 普通函数指针兼容。