3 回答
TA贡献1796条经验 获得超4个赞
有没有人注意到接受的答案仅适用于琐碎的案件?function <> :: target()返回可绑定到C回调的对象的唯一方法是,如果它是用可绑定到C回调的对象构造的。如果真是这样,那么您可以直接绑定它并跳过所有无用的功能。
如果您考虑一下,这没有任何神奇的解决方案。C风格的回调存储为指向可执行代码的单个指针。任何不平凡的boost :: function <>都将至少需要两个指针:一个指向可执行代码,另一个指向建立调用所需的数据(例如,对于绑定成员,则为“ this”指针)功能)。
将boost :: function和boost :: bind与C回调结合使用的正确方法是创建一个满足回调签名的shim函数,找出要调用的函数<>并对其进行调用。通常,C回调对于“用户数据”将具有某种void *;那就是你存放函数指针的地方:
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);
当然,如果您的回调签名不包含某种类型的用户数据指针,那么您就不走运了。但是,任何不包含用户数据指针的回调在大多数实际情况下已经不可用,需要重写。
TA贡献1829条经验 获得超6个赞
我认为您想使用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;
}
TA贡献1847条经验 获得超7个赞
你能和bind一起使用吗?
cb_t cb = *g.target<cb_t>(); //target returns null
这是设计使然。基本上,由于bind返回的是完全不同的类型,因此无法正常工作。基本上,绑定程序代理对象无法转换为C函数指针(因为它不是一个:它是一个函数对象)。返回的类型boost::bind很复杂。当前的C ++标准不允许执行所需的任何好方法。C ++ 0x将配有一个decltype表达式,可在此处用于实现以下目的:
typedef decltype(bind(f, 3)) bind_t;
bind_t target = *g.target<bind_t>();
请注意,这可能会或可能不会。我无法对其进行测试。
- 3 回答
- 0 关注
- 990 浏览
添加回答
举报