Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert C++ function pointer to c function pointer

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?

like image 545
RRR Avatar asked Nov 06 '13 09:11

RRR


People also ask

Can you cast a function pointer?

Yes, it can. This is purpose of casting function pointers, just like usual pointers. We can cast a function pointer to another function pointer type but cannot call a function using casted pointer if the function pointer is not compatible with the function to be called.

Can we use pointer with function in C?

In C, like normal data pointers (int *, char *, etc), we can have pointers to functions. Following is a simple example that shows declaration and function call using function pointer.

What is pointer to a function and function to a pointer?

A pointer to a function points to the address of the executable code of the function. You can use pointers to call functions and to pass functions as arguments to other functions. You cannot perform pointer arithmetic on pointers to functions.


1 Answers

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.

like image 100
Tristan Brindle Avatar answered Sep 17 '22 14:09

Tristan Brindle