3

我正在使用 C++ 中的 Qt 4.8 版开发应用程序。

我需要使用一个需要指向自由函数的指针的 C 函数:

void handler(int dummy)

我需要根据函数内部发生的情况更改 GUI 中显示的值。

所以我一直在阅读如何将成员函数转换为自由函数。我发现只有当我的成员函数是静态的时我才能做到这一点。

但我不能让它成为静态的——如果我让它成为静态的,我将无法更改任何小部件。

那么,我该如何处理这个问题呢?如何将非静态成员函数作为指向自由函数的指针传递。如果不可能,如何解决?

对于使用其他库的任何不同建议,我将不胜感激。

4

2 回答 2

2

由于 C 函数需要一个参数,因此您可以使用该参数作为函数数组的索引:

class MyWidget : public QWidget {
  using vector_t = QVector<std::function<void()>>;
  static vector_t m_functions;
public:
  using function_type = void(*)(int);
  using size_type = vector_t::size_type;

  static function_type getHandler() {
    return +[](int index){ MyWidget::m_functions[index]; };
  }
  template <typename F> static size_type getIndexFor(F && fun) {
    m_functions.append(std::forward<F>(fun));
    return m_functions.size() - 1;
  }
  //...
  size_type getIndexForSetTitle();
};

getHandler返回处理函数的地址。getIndexFor返回要传递给处理程序以运行给定函子的参数。函子可以封装对小部件方法的调用。在这里,我们将调用setWindowTitle小部件:

MyWidget::size_type MyWidget::getIndexForSetTitle() {
  static size_type index = getIndexFor([this]{ setWindowTitle("Foo"); });
  return index;
}
于 2016-02-25T19:10:07.787 回答
1

是的,C++ 不允许将成员函数作为函数指针传递给 C 库。

在这种情况下,一种常见的方法是使用一个辅助函数,它充当 C 库和我们的类实例之间的桥梁。这个辅助函数是一个自由函数,它接受一个指向类的当前实例的指针,并在其主体中调用类实例的相应成员方法。

void handler_helper(int data){
    MyClass *obj = (MyClass *) data;
    obj->handler(); // This is the corresponding member method
}

在你从那个 C 库调用一个函数的地方,你应该handler_helper作为函数指针和(int) this它的参数传递。

于 2016-02-25T16:43:49.683 回答