2016-04-07 1 views
4

Je rencontre un problème lors de la définition et de l'utilisation de la fonction de rappel dans libusb_fill_bulk_transfer lorsqu'elle est appelée en tant que membre d'une classe en C++.libusb callback_in fonction en tant que membre d'une classe en C++

Voici la définition de la classe:

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*); 
... 

Voici la mise en œuvre dans la classe:

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; 
} 

Et voici comment je l'appelle:

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

Le erreur que je reçois est la suivante:

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);

Comment puis-je avoir la fonction de rappel en tant que membre d'une classe et comment puis-je l'appeler?

Répondre

4

Un pointeur vers une fonction de membre de classe et un pointeur vers une fonction sont incompatibles en C++.

Selon la documentation, le prototype de rappel est:

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

Et struct libusb_transfer a le champ user_data, qui remplissent évidemment pendant que vous définissez le rappel, vous avez donc besoin d'une enveloppe:

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); 
} 

Et passer this pendant l'appel:

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

Strictement parlant, 'callback_wrapper()' devrait être 'extern 'C" '. –

+0

@MichaelBurr, je ne pense pas, 'extern' C "' juste désactiver mangling et donner un sens si vous lierez cette fonction contre le fichier plain c objet qui appelle votre fonction C++ par son nom. Mais nous voulons juste appeler fonction par pointeur et n'avoir rien à mangling ici. – user2807083