L
L
LittleBuster2015-07-29 10:43:50
C++ / C#
LittleBuster, 2015-07-29 10:43:50

Function pointer from C library to C++ class?

Let's say we have a C library like this:

struct my_t {
    void (*send_sms)(int);
};

struct my_t *my_new(void)
{
    struct my_t *m;
    m = (struct my_t*)malloc(sizeof(struct my_t));
    return m;
}

void my_test(struct my_t *m)
{
    (*m->send_sms)(545);
}

The question is: how to handle calls to a function pointer in a C++ class?
Tried like this:
MainWindow::MainWindow(QWidget *parent)...
{
    my = my_new();
    my->send_sms = this->test;
...

But the compiler says that the test function must be a static member of the class, and if I make it static, then I can’t process events from the C library, entering their results into the fields of the window class through this. And all that remains for me is to display a MessageBox. I wanted to make a static signal, but the compiler also swears. I need to assign the result to window components, what should I do?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
AxisPod, 2015-07-29
@LittleBuster

Yes, you can't. A method can only be called with 2 pointers, a pointer to an object and a pointer to a function, while the type of the method contains the type of the object. Accordingly, in C, you can only save to 2 pointers, but you cannot call a method from C.
But you can do something like

// C
struct my_t {
    void (*send_sms)(int);
    void* context;
};

void my_test(struct my_t *m)
{
    (m->send_sms)(545, m->context);
}

// C++
void send_sms_helper(int value, void* context) {
  MainWindow *wnd = reinterpret_cast<MainWindow*>(context);
  wnd->test(value);
}

MainWindow::MainWindow(QWidget *parent)...
{
    my = my_new();
    my->send_sms = send_sms_helper;
    my->context = this;

And it is better to make send_sms_helper static in MainWindow.

S
Stanislav Makarov, 2015-07-29
@Nipheris

It's very simple: in order to have less influence on the rest of the C++ code that you have already written, do the following:
1) create a regular function (NOT a member of the class) send_sms, the pointer to which you will give to the link;
2) do everything that is necessary for the task in this function (send SMS? :));
3) implement a singleton (easier) or a service (more correct) for MainWindow in order to be able to access the window instance from the external send_sms function;
4) at MainWindow, pull the test method or any other one to pass the necessary data to it. If you make a singleton, it will be something like this: MainWindow::instance()->test(...);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question