2016-04-07 5 views
4

libusb_fill_bulk_transferでコールバック関数を定義して使用すると、C++のクラスのメンバーとして呼び出されたときに問題が発生します。ここでlibusb callback_inはC++のクラスのメンバーとして機能します

は、クラスの定義です:ここで

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

は、クラスの実装です:

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

そして、ここでは、私はそれを呼び出す方法です:

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

私は次のエラーが発生します:

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

コールバック関数をクラスのメンバーとして使用するにはどうすればよいですか、どのようにコールするのですか?

答えて

4

クラスメンバ関数へのポインタと関数へのポインタは、C++では互換性がありません。

文書によると、コールバックのプロトタイプは次のとおりです。

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

そしてstruct libusb_transferは明らかにあなたの際に記入user_dataフィールドは、コールバックを設定し、そのラッパーが必要があります。

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

通話中にthisを渡します。

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

厳密に言えば、 'callback_wrapper()'は 'extern" C "'でなければなりません。 –

+0

@MichaelBurr、私はそうは思わない、 'extern" C "'は単にmanglingを無効にして、あなたのC++関数を名前で呼ぶプレーンcオブジェクトファイルとこの関数をリンクすると意味があります。しかし、関数をポインタで呼び出すだけで、ここでマングリングを行うことはありません。 – user2807083

関連する問題