简体   繁体   中英

libusb callback_in function as a member of a class in C++

I have a problem defining and using the callback function in libusb_fill_bulk_transfer when called as a member of a class in C++.

Here is the definition in the class:

namespace usb_connector
{
    class USBConnector
    {
    public:
        USBConnector();
        ~USBConnector();
        int connect(void);
        void read(void);
        void write(unsigned char *);
        void disconnect(void);
        void LIBUSB_CALL callback_in(struct libusb_transfer*);
...

Here is the implementation in the class:

void LIBUSB_CALL usb_connector::USBConnector::callback_in(struct libusb_transfer *transfer)
{
    if (transfer == NULL) {
        cout << "No libusb_transfer..." << endl;
    }
    else {
        cout << "libusb_transfer structure: " << endl;
        cout << "actual_length = " << transfer->actual_length << endl;
        for (int i = 0; i < transfer->actual_length; i++) {
            cout << transfer->buffer[i];
        }
        cout << endl;
    }

    return;
}

And here is how I call it:

...
...
libusb_fill_bulk_transfer( transfer_in, usb_dev, USB_ENDPOINT_IN,
            in_buffer,  LEN_IN_BUFFER, callback_in, NULL, 0);
...
...

The error I get is the following:

error: cannot convert 'usb_connector::USBConnector::callback_in' from type 'void (usb_connector::USBConnector::)(libusb_transfer*)' to type 'libusb_transfer_cb_fn {aka void ( )(libusb_transfer )}' in_buffer, LEN_IN_BUFFER, callback_in, NULL, 0);

How can I have the callback function as a member of a class and how do I make a call to it?

A pointer to a class member function and a pointer to a function are incompatible in C++.

According to documentation, the prototype for callback is:

typedef void( * libusb_transfer_cb_fn) (struct libusb_transfer *transfer)

And struct libusb_transfer has the user_data field, which obviously fill in during you set callback, so you need a wrapper:

void LIBUSB_CALL callback_wrapper(struct libusb_transfer *transfer)
{
    usb_connector::USBConnector *connector = reinterpret_cast<usb_connector::USBConnector*>(transfer->user_data);
    connector->callback_in(transfer);
}

And pass this during the call:

...
...
libusb_fill_bulk_transfer( transfer_in, usb_dev, USB_ENDPOINT_IN,
            in_buffer,  LEN_IN_BUFFER, callback_wrapper, this, 0);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM