将仿函数作为函数指针传递

新手上路,请多包涵

我正在尝试在 C++ 应用程序中使用 C 库,并在以下情况下发现了自己(我知道我的 C,但我对 C++ 还很陌生)。在 C 端,我有一组函数,它们以函数指针作为参数。在 C++ 方面,我有一个带有仿函数的对象,它与 C 函数所需的函数指针具有相同的签名。有没有办法使用 C++ 仿函数作为函数指针传递给 C 函数?

原文由 dagw 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

您不能直接将指向 C++ 仿函数对象的指针作为指向 C 代码(甚至 C++ 代码)的函数指针传递。

此外,要将回调可移植地传递给 C 代码,它至少需要声明为 extern "C" 非成员函数。至少,因为某些 API 需要特定的函数调用约定,因此需要额外的声明修饰符。

在许多环境中,C 和 C++ 具有相同的调用约定,并且仅在名称修饰上有所不同,因此任何全局函数或静态成员都可以使用。但是您仍然需要将调用 operator() 包装在一个普通函数中。

  • 如果你的函子没有状态(它只是一个满足一些形式要求等的对象):
   class MyFunctor {
    // no state
   public:
    MyFunctor();
    int operator()(SomeType &param) const;
  }

你可以编写一个普通的外部“C”函数来创建仿函数并执行它的operator()。

   extern "C" int MyFunctorInC(SomeType *param)
  {
    static MyFunctor my_functor;
    return my_functor(*param);
  }

  • 如果你的函子有状态,例如:
   class MyFunctor {
    // Some fields here;
   public:
    MyFunctor(/* some parameters to set state */);
    int operator()(SomeType &param) const;
    // + some methods to retrieve result.
  }

并且 C 回调函数采用某种用户状态参数(通常为 void *):

   void MyAlgorithmInC(SomeType *arr,
                      int (*fun)(SomeType *, void *),
                      void *user_state);

您可以编写一个普通的 extern “C” 函数,将其状态参数转换为您的仿函数对象:

   extern "C" int MyFunctorInC(SomeType *param, void *user_state)
  {
    MyFunctor *my_functor = (MyFunctor *)user_state;
    return (*my_functor)(*param);
  }

并像这样使用它:

   MyFunctor my_functor(/* setup parameters */);
  MyAlgorithmInC(input_data, MyFunctorInC, &my_functor);

  • 否则,唯一正常的方法(正常如“在运行时不生成机器代码”等)是使用一些静态(全局)或线程本地存储将仿函数传递给外部“C”函数。这限制了您可以对代码执行的操作,而且很丑陋,但可以使用。

原文由 Tomek Szpakowicz 发布,翻译遵循 CC BY-SA 3.0 许可协议

我用谷歌找到了这个“ 宝石”。显然可能,但我肯定不会推荐它。直接 链接 到示例源代码。

原文由 Andreas Brinck 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题