如何将提升绑定转换为 C 函数指针或将其转换为 C 函数指针

How can I cast or convert boost bind to C function pointer?

本文关键字:函数 指针 转换 绑定      更新时间:2023-10-16

假设我有这个:

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

我需要像这样将其转换为 void 函数(void):

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

现在我有这样的结构:

typedef void (__cdecl * PFUNCPLUGINCMD)();
struct FuncItem {
PFUNCPLUGINCMD pFunc;
    // ...
};

如何将结构的 pFunc 设置为 bind(func, "something") ?Bind 返回lambda_functor不是函数指针,那么如何将此函子强制转换为函数指针呢?

谢谢。


最终使用了包装"解决方案"(GitHub)

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

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

void uglyWorkaround() {
    globalLambdaFunctor();
}

并将pFunc设置为 uglyWorkaround()

编辑
只是一个旁注:如果你将静态文本绑定到函数调用,你可以完全省略bind()调用,只写:

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

并将pFunc设置为 wrapper()

Bind 返回lambda_functor不是函数指针,那么如何将此函子强制转换为函数指针呢?

我认为你不能。但是,在我的头顶上,我可以想到几种选择:

  • 使用boost::function<void()>(如果编译器支持 TR1 或 C++11,则使用 std::function())而不是 void (*)()
    它能够绑定到具有某种兼容签名的几乎任何东西。

  • 把整个代码放进一个模板里,做PFUNCPLUGINCMD模板参数,让函数模板参数推演找出确切的类型。实际上,这是前者的变体,您将直接使用bind()的结果,而不是boost::function抽象出血腥的细节。

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

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

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

你不能这样做,除非你想编写自己的即时编译器。或者,如果您控制接收代码,则可以使用 boost::function<> ,它将接受各种函数类型,包括指针和函数对象,如 boost::bind 生成的指针函数对象。