降级的boost ::函数为纯函数指针 [英] demote boost::function to a plain function pointer

查看:135
本文介绍了降级的boost ::函数为纯函数指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想的boost ::绑定期望传给一个普通的函数指针(相同的签名)的方法。

 无效的typedef TriggerProc_type(可变*,无效*);
无效InitVariable(TriggerProc_type * PROC);
提振::函数<无效(可变*,无效*)> triggerProc ...
InitVariable(triggerProc);错误C2664:'InitVariable:不能转换参数1从
提振::函数<签署及GT;'为无效(__cdecl *)(键入*,无效*)'

我能避免存储一个boost ::功能,只是直接传递绑定的函子,但后来我得到类似的错误:

 错误C2664:'胡说(无效(__cdecl *)(键入*,无效*)):不能转换参数
1,从提高:: _双:: bind_t< R,F,L>'为无效(__cdecl *)(键入*,无效*)'


解决方案

有没有人注意到,接受的答案只有作品琐碎的案件?该功能与LT的唯一途径;> ::目标()将返回可以绑定到一个C回调,就是如果它与可绑定到一个C回调的对象构造一个对象。如果是这样的话,那么你可能会直接绑定,并跳过所有的功能和LT的;>废话,开始以

如果你想想看,没有任何神奇的解决方案这一点。 C风格的回调被存储为指向的可执行文件code单一指针。任何平凡的boost ::功能<>将需要至少两个指针:一个可执行文件code,另外,以建立呼叫(如这个指针的所需要的数据,在的情况下,绑定的成员函数)。

使用boost ::功能和提高的正确方法::绑定使用C回调是创建满足回调签名的垫片功能,数字输出功能&LT它;>打电话,并调用它。通常是C回调都会有某种无效*为用户数据的;这就是你藏匿的函数指针:

 无效的typedef(* CallbackType)(INT X,无效* USER_DATA);
无效RegisterCallback(CallbackType CB,无效* USER_DATA);无效myCallBack函数(INT X,无效*用户数据){
  提振::函数<无效(INT)> PFN =的static_cast<升压::功能<无效(INT)> >(用户数据);
  PFN(X);
}提振::函数<无效(INT)> FN =的boost ::绑定(myFunction的(5));
RegisterCallback(myCallBack函数,&安培; FN);

当然,如果你的回调签名不包括某种类型的用户数据指针,你的运气了。但是,这并不包括用户数据指针的回调已经在大多数现实世界中无法使用,需要重写。

want to pass boost::bind to a method expecting a plain function pointer (same signature).

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 *)'

I can avoid storing a boost::function and just pass the bound functor directly, but then I get similar error:

error C2664: 'blah(void (__cdecl *)(type *,void *))' : cannot convert parameter
1 from 'boost::_bi::bind_t<R,F,L>' to 'void (__cdecl *)(type *,void *)'

解决方案

Has anyone noticed that the accepted answer only works with trivial cases? The only way that function<>::target() will return an object that can be bound to a C callback, is if it was constructed with an object that can be bound to a C callback. If that's the case, then you could have bound it directly and skipped all of the function<> nonsense to begin with.

If you think about it, there isn't any magic solution to this. A C-style callback is stored as a single pointer which points to executable code. Any nontrivial boost::function<> is going to need at least two pointers: one to the executable code, the other to the data that's needed to set up the call (e.g. the 'this' pointer, in the case of a bound member function).

The right way to use boost::function and boost::bind with C callbacks is to create a shim function that satisfies the callback signature, figures out which function<> to call, and calls it. Usually C callbacks will have some kind of a void* for 'user data'; that's where you stash your function pointer:

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);

Of course, if your callback signature doesn't include some kind of user data pointer, you're out of luck. But any callback that doesn't include a user data pointer is already unusable in most real-world scenarios, and needs to be rewritten.

这篇关于降级的boost ::函数为纯函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆