Post several callbacks as function parameter
I have several functions.
void a();
bool b();
void c(int x, int y);
An one function whats looks like that.
void setListener(void * listenerCallback);
I must send all this functions (a, b, c) as parameters of "setListener" functions.
setListener(&a);
setListener(&b);
setListener(&c);
开发者_StackOverflow社区
How can i make this without overloading setListener function?
I find one variant. Though I think he may be causing problems with memory. But in fact it is same as in the solve from Lundin, only without union.
typedef unsigned int varCallback;
enum callbackType {
C_VOID,
C_BOOL,
C_VOID_INT_INT,
}
void setListener(varCallback callbackPointerAddress, callbackType type) {
/// code
}
void a() {};
bool b() {};
void c(int x, int y) {};
setListener((varCallback)&a, C_VOID);
setListener((varCallback)&b, C_BOOL);
setListener((varCallback)&c, C_VOID_INT_INT);
As you tagged this C, here's a C solution as well (regard as pseudo code):
typedef enum
{
FPTR_VOID_VOID,
FPTR_BOOL_VOID,
FPTR_VOID_INT_INT
} Func_ptr_t;
typedef struct
{
Func_ptr_t type;
union
{
void(*void_void)();
bool(*bool_void)();
void(*void_int_int)(int, int);
};
} My_func_ptr_t;
My_func_ptr_t var = {FPTR_VOID_VOID, &a};
setListener(&var);
EDIT:
(still, regard this as pseudo, I haven't compiled or tested it)
void setListener (void * listenerCallback)
{
const My_func_ptr_t* func_ptr;
func_ptr = (const My_func_ptr_t*) listenerCallback;
switch(func_ptr->type)
{
case FPTR_VOID_VOID:
{
func_ptr->void_void();
break;
}
...
}
}
EDIT 2:
Btw it should be noted that this is the only way to pass several function pointers around generically in C. Wild typecasts from one function pointer to another pointer type is undefined behaviour.
You can try writing function template and functor.
Example:
void a();
bool b();
void c(int x, int y);
template<typename Fun>
void setListener(Fun listenerCallback);
template<typename Fun, typename TArg1, typename TAgr2, typename R>
struct Functor
{
Fun m_fun;
TArg1 m_arg1;
TArg2 m_arg2;
Functor(Fun fun, TArg1 arg1, TArg2 arg2)
: m_fun(fun), m_arg1(arg1), m_arg2(arg2) {}
R operator()()
{
return m_fun(arg1, arg2);
}
};
Functor<void (*)(int,int), int, int, void> c_fun(c, 10, 20);
setListener(&a);
setListener(&b);
setListener(c_fun);
10
and 20
are argument to function c(int, int)
.
Note: this is not very generic solution, this is specific to the problem asked here.
精彩评论