HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Wrapping libusb library in C++

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
libusbwrappinglibrary

Problem

I want to use libusb library in my C++ application. I have created classes which wraps libusb functions. You can see that libusb API is split into 8 sections:

http://libusb.sourceforge.net/api-1.0/modules.html

For me the most necessary sections are:

  • Device handling and enumeration



  • Synchronous device I/O



  • Library initialization/deinitialization



  • Miscellaneous



I have also split "Device handling and enumeration" section to "Device Info" and "Device Handling". To use libusb functions it is need to initialize libusb library (call libusb_init function), store somewhere its initialized libusb_context , next - call functions (libusb_get_device_list, libusb_open_device_with_vid_pid) to obtain and store somewhere "device pointer" (in libusb known as libusb_device or libusb_device_handle), and then finally call functions for obtaining device info or performing some USB transfers (for instance: libusb_set_configuration, libusb_get_bus_number). Note, that these functions require "device pointer": libusb_device_handle or libusb_device_* as first parameter. You can see whole process of initializing/opening/controlling device here:

http://www.dreamincode.net/forums/topic/148707-introduction-to-using-libusb-10/

Currenlty my solution consists of following classes:

  • LibusbInfoAPI: provides functions to obtain device info



  • LibusbControlAPI: provides functions to control device



  • LibusbHandlingAPI: creates devices, destroys, manages them, and stores libusb_context , libusb_device , libusb_device_handle *



LibusbControlAPI header:

```
class LibusbControlAPI
{
public:
int GetConfiguration(DevHandlePtr deviceHandle, int& activeConfiguration);
int SetConfiguration(DevHandlePtr deviceHandle, int targetConfiguration);

int ClaimInterface(DevHandlePtr deviceHandle, int interfaceNumber);
int ReleaseInterface(DevHandlePtr deviceHandle, int interfaceNumber);
int SetInterfaceAlternateSetting(DevHandlePtr deviceHandle, int int

Solution

It is kind of hard to say without seeing the whole code but at a glance the whole thing seems kind of pointless to me. You're not making it object oriented but rather just adding your own "flavor" API over libusb.

I can tell this by the fact that I see a DevHandlePtr deviceHandle being passed around just about everywhere.

If you want to actually make a useful C++ API then you need to find usable objects in the existing API and structure your code around these objects instead. You'll know you have done it right when you stop passing "handles" around in your API.

Without reading the libusb API fully, I'll make an example to show what I mean:

class UniversalSerialBus{
public: 
    UniversalSerialBus(){
       // Initialize libusb
    }
    ~UniversalSerialBus(){
       // Shutdown libusb
    }

    std::vector enumerateDevices() const;

    USBDeviceContext createDevice(USBDeviceIdentifier id);
}

class USBDeviceIdentifier{
public:
    int getVendorID();
    int getProductID();
    int getBusNumber();
    int getPorNumber();
    //...

}

class USBDeviceContext{
public:
    USBDeviceContext(){ /* Connect to the device */ }
    ~USBDeviceContext(){ /* Disconnect the device */ }

    bool SendInterrupt(int, int)
    bool SendBlockTransfer(int, int, Iterator dataBegin, Iterator dataEnd);
}


I hope this helps.

Code Snippets

class UniversalSerialBus{
public: 
    UniversalSerialBus(){
       // Initialize libusb
    }
    ~UniversalSerialBus(){
       // Shutdown libusb
    }

    std::vector<USBDeviceIdentifier> enumerateDevices() const;

    USBDeviceContext createDevice(USBDeviceIdentifier id);
}

class USBDeviceIdentifier{
public:
    int getVendorID();
    int getProductID();
    int getBusNumber();
    int getPorNumber();
    //...

}

class USBDeviceContext{
public:
    USBDeviceContext(){ /* Connect to the device */ }
    ~USBDeviceContext(){ /* Disconnect the device */ }

    bool SendInterrupt(int, int)
    bool SendBlockTransfer(int, int, Iterator dataBegin, Iterator dataEnd);
}

Context

StackExchange Code Review Q#156701, answer score: 7

Revisions (0)

No revisions yet.