我正在设置一个成员函数作为我正在使用的C库的回调。 C库设置了这样的回调:
typedef int (*functionPointer_t)(myType1_t*, myType2_t*, myType3_t*);
setCallback(param1, param2, functionPointer, param4)
我想使用boost :: bind(如果可能的话)传入函数指针。我希望指向的函数是实例化类的成员,而不是静态成员。 E.g。
Class A {
public:
A();
protected:
int myCallback(myType1_t*, myType2_t*, myType3_t*); //aka functionPointer_t
}
这可以使用boost :: bind和boost :: function来完成吗?根据{{3}}(第3个答案),我可以声明以下内容(某处或作为typedef):
boost::function<int (A*, myType1_t*, myType2_t*, myType3*> myCallbackFunction
然后在A(ctor)中的某处调用boost :: bind在该类型上,并将其传递给C库调用。
这可能吗,还是我偏离基地?非常感谢。
答案 0 :(得分:5)
没有。像boost::function
这样的函数类型不会转换为函数指针以与C回调机制一起使用。
但是,大多数C回调机制都有某种令牌机制,因此您的回调函数(它是静态的)具有某种上下文信息。您可以使用它来编写一个包装类,将这些标记映射到仿函数对象,并将执行传递到右侧:
class CallbackManager {
public:
typedef boost::function<int (type1*, type2*, type3*)> callback;
static void setCallback(CallbackManager::callback cb)
{
void *token = ::setCallback(staticCallback);
callbacks[token] = callback_I;
}
static void staticCallback(void* token, type1* a, type2* b, type3* c)
{ return mcallbacks[token](a, b, c); }
private:
static std::map<void*, callback > callbacks;
};
答案 1 :(得分:1)
不使用map,它会产生运行时开销,并使用静态映射来混淆代码。
改为使用reinterpret_cast
。
// clib.h
typedef void (*CALLBACK_FUNC)(int code,void *param);
void set_callback( CALLBACK_FUNC, void * param );
// a.h
class A {
public:
A()
{
::set_callback( &A::static_callback, this);
}
private:
static void static_callback(int code, void * param)
{
A* self = reinterpret_cast<A*>(param);
self->callback( code );
}
inline void callback( int code )
{
// write you code here.
}
};
答案 2 :(得分:0)
成员函数的问题在于它们自动接收指向对象实例的指针作为第一个参数 - “this”指针。这就是为什么你不能使用成员函数C回调函数。您必须将对象和函数指针放在一起才能使用成员函数。