I'm working on an application using Qt version 4.8 in C++.
I need to use a C function which requires a pointer to a free function:
void handler(int dummy)
I need to change the displayed values in my GUI depending on what happens inside the function.
So I've been reading on how to convert a member function to a free function. I've found out that I can do it only if my member function is static.
But I can't make it static - I won't be able to change any widgets if I make it static.
So, how can I deal with the problem? How can I pass a non-static member function as a pointer to a free function. If it's not possible, how to make a workaround?
I'll be grateful for any suggestions different that use another library.
Since the C function takes an argument, you can use the argument as an index into an array of functors:
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();
};
The getHandler returns the address of the handler function.
The getIndexFor returns the argument to be passed to the handler to run a given functor. The functor can encapsulate calls to the widget's methods. Here, we'll call setWindowTitle on the widget:
MyWidget::size_type MyWidget::getIndexForSetTitle() {
static size_type index = getIndexFor([this]{ setWindowTitle("Foo"); });
return index;
}
Yes, C++ does not allow member functions to be passed as a function pointer to C libraries.
In this cases a common approach is using a helper function that acts like a bridge between the C library and our class instance. This helper function is a free function that takes a pointer to the current instance of the class and in its body invoke the corresponding member method of the class instance.
void handler_helper(int data){
MyClass *obj = (MyClass *) data;
obj->handler(); // This is the corresponding member method
}
And where you invoke a function from that C library, you should pass handler_helper as the function pointer and (int) this as its argument.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With