In my C++ code I have a dependecy on a C library. This C library lets me define a callback with 3 arguments. Example:
file.c:
#ifdef __cplusplus
extern "C"{
#endif
typedef void(*callback)(argument* 1, argument* 2, argument* 3);
...
void set_callback(ARG1, callback name_of_callback);
...
In the C++ library i'm developing i want this callback to be a member function of a class, since I cannot pass directly a member function as the callback to the C library I created a static function to be the callback and inside this static function I want to have a reference to a class object and call its member function to do the work.
Now my problem is that my static functions needs to have the 3 arguments specified by the C library, so i'm not finding a way of having a reference to an object of the class i'm developing inside that static function. Example of I wanted to do:
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);
}
The reason to not set the class members as static is that i want to be able to create and destroy objects of this class for testing purposes and control the state of the object within the tests.
I'm using g++ and gcc, hope someone can give some help with this. Thanks in advance.
You can create a static member function or a pure 'C' function to do this, consider my example below:
/**
* 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 ();
}
Output:
C Lib core...
result = 3
I pass a pointer to the C++ object as argument 1. This allows the callback to cast it back to C++ and call it. The c_lib_core stuff is just so I can simulate the callback of the callback function for testing purposes. This, along with the global variables will be in the C code somewhere. You only need to implement a single C function and set ARG1 to your object and you are good to go.
Assuming no concurrency concerns, which i don't know if it's the case, the simpler solution could be to define an static instance and use that in your static function.
Something like this.
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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.