Convert C++ function pointer to c function pointer

RRR picture RRR · Nov 6, 2013 · Viewed 22.5k times · Source

I am developing a C++ application using a C library. I have to send a pointer to function to the C library.

This is my class:

 class MainWindow : public QMainWindow {  
     Q_OBJECT  
     public:  
     explicit MainWindow(QWidget *parent = 0);  
     private:  
     Ui::MainWindow *ui;
     void f(int*);

 private slots:
     void on_btn_clicked(); 
};

This is my on_btn_clicked function:

void MainWindow::on_btn_clicked()
{
    void (MainWindow::* ptfptr) (int*) = &MainWindow::f;

    c_library_function(static_cast<void()(int*)>(ptfptr), NULL);

}

The C function should get a pointer to a such function : void f(int*). But the code above doesn't work, I cannot succeed to convert my f member function to the desired pointer.

Can anybody please help?

Answer

Tristan Brindle picture Tristan Brindle · Nov 6, 2013

You can't pass a non-static member function pointer as an ordinary function pointer. They're not the same thing, and probably not even the same size.

You can however (usually) pass a pointer to a static member function through C. Usually when registering a callback in a C API, you also get to pass a "user data" pointer which gets passed back to your registered function. So you can do something like:

class MyClass
{

    void non_static_func(/* args */);

public:
    static void static_func(MyClass *ptr, /* other args */) {
        ptr->non_static_func(/* other args */);
    }
};

Then register your callback as

c_library_function(MyClass::static_func, this);

i.e. pass the instance pointer to the static method, and use that as a forwarding function.

Strictly speaking for total portability you need to use a free function declared extern "C" rather than a static member to do your forwarding (declared as a friend if necessary), but practically speaking I've never had any problems using this method to interface C++ code with GObject code, which is C callback-heavy.