2014-04-13 53 views
4

在我的C++代码中,我对C库有一个依赖关系。这个C库让我用3个参数定义一个回调函数。例如:C++静态成员函数作为C回调需要访问非静态引用

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,希望有人可以提供一些帮助。 在此先感谢。

+3

它看起来像你的'set_callback'调用提供了稍后传递给回调的参数之一?通过该参数传递你的'MyClass *'。 –

回答

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++并调用它。 c_lib_core的东西就是这样,我可以模拟回调函数的回调用于测试目的。这和全局变量一起在C代码中。你只需要实现一个C函数并将ARG1设置为你的对象,你就可以走了。

+0

我使用指向我的对象的全局指针,set_callback函数和my_callback实现了上述解决方案。 set_callback函数是从类构造函数的C++端调用的。我已经能够在这个解决方案和下面的解决方案下通过相同的测试。我只是想知道关于内存使用情况,如果这个解决方案比静态功能和类的静态成员更好?目标是在资源非常有限的微控制器中使用此代码。谢谢 – mgfernandes

+0

静态成员应该使用与定义一次相同的内存。他们可能是vtptrs的入口,但不确定这是诚实的。如果他们的处理器是如此关心内存的话,或许纯C就是要走的路,所以你不需要同时包含C和C++运行时库,这些内存问题远远超过了几个字节的内存问题 – Chris

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

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

+0

对不起。无论如何,你仍然可以创建和销毁对象,并在测试中控制它们的状态。为什么将类成员定义为静态可以防止这样做? – perencia

+0

我想确保在test1上创建一个具有一个状态(p.ex.对象具有ID = 1)的成员的MyClass,并且当事件发生时,回调执行成员函数,在test2上,我想创建一个MyClass成员处于另一个状态(对象具有ID = 5),并且回调执行相同的成员函数。我的印象是声明静态对象,强制对象处于编译时定义的状态。 – mgfernandes

相关问题