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

时间:2014-04-13 21:31:01

标签: c++ c static callback extern

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

file.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,希望有人可以提供一些帮助。 提前谢谢。

2 个答案:

答案 0 :(得分:1)

您可以创建静态成员函数或纯粹的' 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设置为你的对象,你就可以了。

答案 1 :(得分:0)

假设没有并发问题,我不知道是否是这种情况,更简单的解决方案可能是定义静态实例并在静态函数中使用它。

像这样。

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;
}