想要将boost :: bind传递给期望普通函数指针(相同签名)的方法。
typedef void TriggerProc_type(Variable*,void*);
void InitVariable(TriggerProc_type *proc);
boost::function<void (Variable*, void*)> triggerProc ...
InitVariable(triggerProc);
error C2664: 'InitVariable' : cannot convert parameter 1 from
'boost::function<Signature>' to 'void (__cdecl *)(type *,void *)'
我可以避免存储boost :: function并直接传递绑定的functor,但后来我得到了类似的错误:
error C2664: 'blah(void (__cdecl *)(type *,void *))' : cannot convert parameter
1 from 'boost::_bi::bind_t<R,F,L>' to 'void (__cdecl *)(type *,void *)'
答案 0 :(得分:41)
是否有人注意到accepted answer仅适用于琐碎的案件?函数&lt;&gt; :: target()将返回一个可绑定到C回调的对象的唯一方法是,它是否使用可绑定到C回调的对象构造。如果是这种情况,那么您可以直接绑定它并跳过所有函数&lt;&gt;废话开始。
如果你仔细想想,没有任何神奇的解决方案。 C样式的回调存储为指向可执行代码的单个指针。任何重要的boost :: function&lt;&gt;将需要至少两个指针:一个指向可执行代码,另一个指向设置调用所需的数据(例如,在绑定成员函数的情况下为'this'指针)。
使用boost :: function和boost :: bind与C回调的正确方法是创建一个满足回调签名的填充函数,找出哪个函数&lt;&gt;打电话给它。通常C回调对于'用户数据'会有某种无效*;这就是你存储你的函数指针的地方:
typedef void (*CallbackType)(int x, void* user_data);
void RegisterCallback(CallbackType cb, void* user_data);
void MyCallback(int x, void* userData) {
boost::function<void(int)> pfn = static_cast<boost::function<void(int)> >(userData);
pfn(x);
}
boost::function<void(int)> fn = boost::bind(myFunction(5));
RegisterCallback(MyCallback, &fn);
当然,如果你的回调签名不包含某种用户数据指针,那你就不走运了。但是,任何不包含用户数据指针的回调在大多数现实场景中都已无法使用,需要重写。
答案 1 :(得分:11)
我认为你想使用boost :: function的target()成员函数(不是那么满口......)
#include <boost/function.hpp>
#include <iostream>
int f(int x)
{
return x + x;
}
typedef int (*pointer_to_func)(int);
int
main()
{
boost::function<int(int x)> g(f);
if(*g.target<pointer_to_func>() == f) {
std::cout << "g contains f" << std::endl;
} else {
std::cout << "g does not contain f" << std::endl;
}
return 0;
}
答案 2 :(得分:3)
你可以使用bind吗?
cb_t cb = *g.target<cb_t>(); //target returns null
这是by design。基本上,由于bind
返回一个完全不同的类型,因此无法使用它。基本上,绑定器代理对象不能转换为C函数指针(因为它不是一个:它是一个函数对象)。 boost::bind
返回的类型很复杂。当前的C ++标准没有任何好的方法来做你想做的事情。 C ++ 0x将使用decltype
表达式,可以在此处使用它来实现类似的结果:
typedef decltype(bind(f, 3)) bind_t;
bind_t target = *g.target<bind_t>();
请注意,这可能会也可能不会奏效。我无法测试它。
答案 3 :(得分:2)
答案 4 :(得分:0)
你可以使用bind吗?
#include <boost/function.hpp>
#include <boost/bind.hpp>
void f(int x)
{
(void) x;
_asm int 3;
}
typedef void (*cb_t)(int);
int main()
{
boost::function<void (int x)> g = boost::bind(f, 3);
cb_t cb = *g.target<cb_t>(); //target returns null
cb(1);
return 0;
}
更新:好的,目的是将方法绑定到函数回调中。那么现在呢?