I am trying to callback C++ class methods from C. Now I have got something working, but am not sure if this is the best solution.
I am looking for feedback, as to if there is something wrong with this approach, and how could I make this better.
So, here goes my code:
This is the C++ class Foo
. The class has the methods getValue()
& setValue()
, which I would like to like to be called-back from the C code:
Contents of Foo.h
:
#ifdef __cplusplus
class Foo
{
public:
Foo();
int getValue() const;
void setValue(int value);
private:
int value_;
};
#endif
// Free functions
int c_wrapper_getValue(void *arg1);
void c_wrapper_setValue(int value, void *arg1);
Contents of the source file, Foo.cpp
:
#include "Foo.h"
Foo::Foo() :
value_{0}
{}
int Foo::getValue() const
{
return value_;
}
void Foo::setValue(int value)
{
value_ = value;
}
void c_wrapper_setValue(int value, void *arg1)
{
Foo* foo_instance = static_cast<Foo*>(arg1);
foo_instance->setValue(value);
}
int c_wrapper_getValue(void *arg1)
{
Foo* foo_instance = static_cast<Foo*>(arg1);
return foo_instance->getValue();
}
Here is the code for the C files, which in turn call the Foo
class members. First, the header Test.h
file:
#include <stdio.h>
#include "Foo.h"
#ifdef __cplusplus
extern "C" {
#endif
// Callback function pointers
typedef int (*get_handler_t)(void* arg1);
typedef void (*set_handler_t)(int foo, void* arg1);
void register_handler(get_handler_t g, set_handler_t s, void* p_instance);
// These are the functions which call the callback functions
int call_cpp_get_function();
void call_cpp_set_function(int value);
#ifdef __cplusplus
}
#endif
And finally the Test.c
file:
#include "Test.h"
static get_handler_t get_handler_ = NULL; /**< Getter function pointer of type int (*g)(void *). */
static set_handler_t set_handler_ = NULL; /**< Setter function pointer of type void (*s)(int, void *). */
static void* foo_object_instance = NULL; /**< Instance of Foo object. */
//! Registers the getter and setter function with the object of Class Foo
//! \param g Getter function pointer of type int (*g)(void *).
//! \param s Setter function pointer of type void (*s)(int, void *).
//! \param p_instance Instance of Foo object.
void register_handler(
int (*g)(void *),
void (*s)(int, void *),
void* p_instance)
{
get_handler_ = g;
set_handler_ = s;
foo_object_instance = p_instance;
}
//! Function calls the get function of class Foo
//! \return Value of value_ from class Foo
int call_cpp_get_function()
{
return get_handler_(foo_object_instance);
}
//! Function calls the set function of class Foo
//! \param value Value to be set in class Foo
void call_cpp_set_function(int value)
{
set_handler_(value, foo_object_instance);
}
Now I could create an object and call the functions present in my C file, which called back the C++ methods, like this:
Foo foo_object;
register_handler(&c_wrapper_getValue, &c_wrapper_setValue, static_cast<void *>(&foo_object));
call_cpp_get_function();
call_cpp_set_function(35);
I do have some constraints in my case, for example I can't use STL, since the code is supposed to run on an embedded system. So, how bad is my code?