如何将boost绑定转换为C函数指针?

时间:2011-05-11 10:45:16

标签: c++ boost

假设我有这个:

void func(WCHAR* pythonStatement) {
  // Do something with pythonStatement
}

我需要将它转换为void function(void),如下所示:

bind(func, TEXT("console.write('test')"))

现在我有这样的结构:

typedef void (__cdecl * PFUNCPLUGINCMD)();

struct FuncItem {
PFUNCPLUGINCMD pFunc;
    // ...
};

如何将我的结构的pFunc设置为bind(func, "something")?绑定返回lambda_functor而不是函数指针,那么如何将这个函子转换为函数指针?

感谢。


使用the wrapping "solution"(GitHub)

结束

3 个答案:

答案 0 :(得分:6)

我认为你不能,除非你把结果lamba_functor变成一个全局变量。

在这种情况下,您可以声明一个调用它的函数:

void uglyWorkaround() {
    globalLambdaFunctor();
}

并将pFunc设置为uglyWorkaround()

修改
只是旁注:如果您将静态文本绑定到函数调用,则可以完全省略bind()调用并写入:

void wrapper() {
    func(TEXT("console.write('test')"));
}

并将pFunc设置为wrapper()

答案 1 :(得分:4)

  

绑定返回lambda_functor而不是函数指针,那么如何将这个仿函数转换为函数指针?

我认为你不能。然而,在我的头脑中,我可以想到几个选择:

  • 使用boost::function<void()>(或std::function(),如果您的编译器支持TR1或C ++ 11)而不是void (*)()
    它能够通过稍微兼容的签名绑定到任何东西。

  • 将整个代码放入模板中,使PFUNCPLUGINCMD成为模板参数,让函数模板参数推导出确切的类型。 实际上,这是前者的变体,您可以直接使用bind()的结果,而不是让boost::function抽象出血腥的细节。

  • 创建一个调用boost::bind()返回的仿函数的包装器 函数模板可能有助于让编译器找出确切的类型并生成合适的函数,尽管我没有尝试过这样做。但是,由于您不能使用bind()的结果作为模板参数,但是需要让函数访问它,您需要一个全局变量。 (避免这种情况的能力是功能对象的主要优点之一,其中通用的std::function非常通用。)

  • 扩展您的PFUNCPLUGINCMD回调类型以支持用户提供的参数。对于C回调,这通常是void*。但是,如果将bind()返回的对象的地址传递给回调,则需要将其转换为指向正确类型的指针 - AFAIK取决于提供给bind()的参数。为了避免这种情况,你需要传递抽象出确切类型的东西。再次,std::function来救援。

第一个想法是最好的,但它要求您能够更改PFUNCPLUGINCMD。当PFUNCPLUGINCMD需要与C兼容时,最后一个可能是最好的,因为它使用常见的C回调习惯用法。

答案 2 :(得分:0)

除非您想编写自己的即时编译器,否则不能这样做。或者,如果您控制接收代码,那么您可以使用boost::function<>,其中接受各种函数类型,包括指针等函数对象由boost::bind制作。