为了账号安全,请及时绑定邮箱和手机立即绑定

将boost :: function降级为普通函数指针

将boost :: function降级为普通函数指针

C++
慕桂英4014372 2019-10-11 10:58:27
想要将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,而直接通过绑定的函子,但是然后我得到类似的错误:error C2664: 'blah(void (__cdecl *)(type *,void *))' : cannot convert parameter1 from 'boost::_bi::bind_t<R,F,L>' to 'void (__cdecl *)(type *,void *)'
查看完整描述

3 回答

?
SMILET

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

当然,如果您的回调签名不包含某种类型的用户数据指针,那么您就不走运了。但是,任何不包含用户数据指针的回调在大多数实际情况下已经不可用,需要重写。


查看完整回答
反对 回复 2019-10-11
?
肥皂起泡泡

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;

}


查看完整回答
反对 回复 2019-10-11
?
aluckdog

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

请注意,这可能会或可能不会。我无法对其进行测试。


查看完整回答
反对 回复 2019-10-11
  • 3 回答
  • 0 关注
  • 939 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信