C++静态成员函数作为C回调函数需要访问非静态引用

C++ static member function as C callback needs to access non static reference

本文关键字:函数 访问 静态 引用 回调 静态成员 C++      更新时间:2023-10-16

在我的C++代码中,我依赖于C库。这个C库允许我定义一个带有3个参数的回调。示例:

文件.c:

#ifdef __cplusplus
extern "C"{
#endif
     typedef void(*callback)(argument* 1, argument* 2, argument* 3);
...
     void set_callback(ARG1, callback name_of_callback);
...

在我正在开发的C++库中,我希望这个回调是一个类的成员函数,因为我不能直接将成员函数作为回调传递给C库,所以我创建了一个静态函数作为回调,在这个静态函数中,我想引用一个类对象并调用其成员函数来完成工作。

现在我的问题是,我的静态函数需要有C库指定的3个参数,所以我找不到一种方法来引用我在该静态函数中开发的类的对象。我想做的例子:

MyClass.h:

class MyClass:
public:
   MyClass();
   void my_function(argument*1, argument* 2, argument* 3);
   static void my_callback(argument* 1, argument* 2, argument*3);

MyClass.cpp:

MyClass::MyClass(){
    set_callback(ARG1, my_callback);
}
void MyClass::my_function(argument*1, argument* 2, argument* 3){ 
      /* Do something */}
void MyClass::my_callback(argument* 1, argument* 2, argument*3){
    Object->my_function(1, 2, 3);
}

不将类成员设置为静态的原因是,我希望能够为测试目的创建和销毁此类的对象,并控制测试中对象的状态。

我正在使用g++和gcc,希望有人能在这方面提供一些帮助。提前谢谢。

您可以创建一个静态成员函数或纯"C"函数来实现这一点,请考虑下面的示例:

/**
 * C++ part
 */
class obj
{
public:
    obj() {}
    ~obj() {}
    void doSomething(int a, int b) { cout << "result = " << a+b << endl; }
};
/**
 * C Part
 */
#ifdef __cplusplus
extern "C"
#endif
{
typedef void (*callback)(void* one, void* two, void* three);
callback g_ptr = NULL;
void* arg = NULL;
void c_lib_core (void)
{
    printf ("C Lib core...n");
    if (g_ptr)
    {
        g_ptr(arg, NULL, NULL);
    }
}
void set_callback (void* arg, callback ptr)
{
    g_ptr = ptr;
}
void my_callback (void* one, void* two, void* three)
{
    obj* my_obj = (obj*) one;
    my_obj->doSomething(1,2);
}
#ifdef __cplusplus
}
#endif

int main (void)
{
    obj a;
    set_callback (&a, my_callback);
    c_lib_core ();
}

输出:

C Lib core...
result = 3

我传递一个指向C++对象的指针作为参数1。这允许回调将其强制转换回C++并调用它。C_lib_core的内容只是为了便于我模拟回调函数的回调以进行测试。这与全局变量一起将在C代码中的某个位置。您只需要实现一个C函数,并将ARG1设置为您的对象,就可以开始了。

假设没有并发问题(我不知道是不是这样),更简单的解决方案可以是定义一个静态实例并在静态函数中使用它。

像这样的东西。

MyClass.h

class Object;
class MyClass
{
public:
    MyClass();
    static Object* object;
    static void callback();
    ~MyClass();
};

MyClass.cpp

Object* MyClass::object;
MyClass::MyClass()
{
    object = new Object();
}
void MyClass::callback() {
    object->sayHello();
}
MyClass::~MyClass()
{
    delete object;
}