当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《将boost::function降级为普通函数指针》经验,为你挑选了2个好方法。

想要将boost :: bind传递给期望普通函数指针(相同签名)的方法.

typedef void TriggerProc_type(Variable*,void*);
void InitVariable(TriggerProc_type *proc);
boost::function triggerProc ...
InitVariable(triggerProc);

error C2664: 'InitVariable' : cannot convert parameter 1 from 
'boost::function' to 'void (__cdecl *)(type *,void *)'

我可以避免存储boost :: function并直接传递绑定的functor,但后来我得到类似的错误:

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

Ian Ni-Lewis.. 41

有没有人注意到接受的答案只适用于琐碎的案件?函数<> :: target()将返回一个可以绑定到C回调的对象的唯一方法是,它是使用可以绑定到C回调的对象构造的.如果是这种情况,那么你可以直接绑定它并跳过所有函数<>废话开始.

如果你仔细想想,没有任何神奇的解决方案.C样式的回调存储为指向可执行代码的单个指针.任何重要的boost :: function <>都需要至少两个指针:一个指向可执行代码,另一个指向设置调用所需的数据(例如,'this'指针,如果是绑定成员功能).

使用boost :: function和boost :: bind与C回调的正确方法是创建一个满足回调签名的shim函数,找出要调用的函数<>并调用它.通常C回调对于'用户数据'会有某种无效*; 这是你存储函数指针的地方:

typedef void (*CallbackType)(int x, void* user_data);
void RegisterCallback(CallbackType cb, void* user_data);

void MyCallback(int x, void* userData) {
  boost::function pfn = static_cast >(userData);
  pfn(x);
}

boost::function fn = boost::bind(myFunction(5));
RegisterCallback(MyCallback, &fn);

当然,如果你的回调签名不包含某种用户数据指针,那你就不走运了.但是,任何不包含用户数据指针的回调在大多数现实场景中都已无法使用,需要重写.



1> Ian Ni-Lewis..:

有没有人注意到接受的答案只适用于琐碎的案件?函数<> :: target()将返回一个可以绑定到C回调的对象的唯一方法是,它是使用可以绑定到C回调的对象构造的.如果是这种情况,那么你可以直接绑定它并跳过所有函数<>废话开始.

如果你仔细想想,没有任何神奇的解决方案.C样式的回调存储为指向可执行代码的单个指针.任何重要的boost :: function <>都需要至少两个指针:一个指向可执行代码,另一个指向设置调用所需的数据(例如,'this'指针,如果是绑定成员功能).

使用boost :: function和boost :: bind与C回调的正确方法是创建一个满足回调签名的shim函数,找出要调用的函数<>并调用它.通常C回调对于'用户数据'会有某种无效*; 这是你存储函数指针的地方:

typedef void (*CallbackType)(int x, void* user_data);
void RegisterCallback(CallbackType cb, void* user_data);

void MyCallback(int x, void* userData) {
  boost::function pfn = static_cast >(userData);
  pfn(x);
}

boost::function fn = boost::bind(myFunction(5));
RegisterCallback(MyCallback, &fn);

当然,如果你的回调签名不包含某种用户数据指针,那你就不走运了.但是,任何不包含用户数据指针的回调在大多数现实场景中都已无法使用,需要重写.



2> coryan..:

我想你想使用boost :: function的target()成员函数(不是那么满口......)

#include 
#include 

int f(int x)
{
  return x + x;
}

typedef int (*pointer_to_func)(int);

int
main()
{
  boost::function g(f);

  if(*g.target() == f) {
    std::cout << "g contains f" << std::endl;
  } else {
    std::cout << "g does not contain f" << std::endl;
  }

  return 0;
}

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有