1

I am working in libusb and have minimal knowledge on C++. I am trying to understand the API of libusb and write code accordingly. But I am unable to understand how to declare and use variables as variable or pointer or double or triple pointer.

  1. The below code is from question. How to find what level of pointers to be used while declaring these variables from the API documentation. Is there any documentation or tutorial videos that explains these things.

    libusb_context       *context    = NULL   ;
    libusb_device_handle *dev_handle = NULL   ;
    libusb_device        **devs               ;
    int                  rc          = 0      ;
    ssize_t              count                ; //holding number of devices in list
    

For example, consider libusb_device_handle. How to declare this and use it?

typedef struct libusb_device_handle libusb_device_handle
  1. The syntax of libusb_strerror() is const char * libusb_strerror (int errcode). The function returns constant string. Should I declare a char or char array or string to read the returned value. If the below way of usage right?

     char char *err_code;//declaration
     err_code = libusb_strerror(rc);
    

if the returned value is a string, then how can a characer pointer hold it?

An example would be really helpful.

3)Here is my entire code. I can open the device. But the bulk transfer command returns 5 and fails. I am not sure at which part I am making mistake.

#include <iostream>
#include "libusb.h"

#define IN_EP  0x81
#define OUT_EP 0x02

int main(){
    libusb_context *context = NULL;
    libusb_device_handle *dev_handle = NULL ;
    libusb_device **devs ;
    int rc = 100 ;
    //ssize_t count ; //holding number of devices in list
    unsigned int vid=0x1234;
    unsigned int pid=0x5678;
    unsigned char data[10];
    data[0]=128;
    int transferred = 0;
    unsigned int timeout = 5000;
    //std::string str[100];
    const char* err_code;
    

    rc = libusb_set_option(context, LIBUSB_OPTION_LOG_LEVEL,2);
    if (rc==0){    std::cout<<"libusb_setOption worked:"<<rc<<"\n"; }
    else{   std::cout<<"libusb_setOption_Failed:"<<rc<<"\n";    }


    rc = libusb_init(&context);
    if (rc==0){    std::cout<<"libusb_init worked:"<<rc<<"\n"; }
    else{   std::cout<<"libusb_init Failed"<<rc<<"\n";    }


    dev_handle = libusb_open_device_with_vid_pid(context,vid,pid);
    if (dev_handle == NULL){
        std::cout<<"libusb_open Failed"<<"\n";
        libusb_exit(context);std::cout<<"libusb_exit"<<"\n";exit(1);    }
    else{    std::cout<<"libusb_opened"<<"\n";    }

    
    rc = libusb_bulk_transfer(dev_handle,OUT_EP,data,1,&transferred, timeout);  //Send data to device
    if (rc==0){        std::cout<<"libusb_write worked:"<<rc<<"; Wrote "<<transferred<<" bytes\n";    }
    else{        std::cout<<"libusb__Write failed"<<rc<<"; Wrote "<<transferred<<" bytes\n";    }
    err_code = libusb_strerror(rc);
    
    rc = libusb_bulk_transfer(dev_handle,IN_EP,data,3,&transferred, timeout);   //Read data from device
    if (rc==0){        std::cout<<"libusb_read worked:"<<rc<<" ; Read"<<transferred<<" bytes; Data:"<<data<<"\n";
    std::cout<<data[0]<<" "<<data[1]<<" "<<data[2]<<"\n";  }
    else{        std::cout<<"libusb__read failed"<<rc<<"; Read "<<transferred<<" bytes\n";    }

    
    libusb_close(dev_handle);
    std::cout<<"libusb_close"<<"\n";
    
    
    libusb_exit(context);
    std::cout<<"libusb_close"<<"\n";
    
    
    return 0;
    }

Any help will be appreciated.

1 Answers1

1
  1. [...] For example, consider libusb_device_handle. How to declare this and use it?

You declare it exactly like in your code:

libusb_device_handle *dev_handle = NULL;

Because libusb_open_device_with_vid_pid() returns a pointer to libusb_device_handle, your dev_handle must also be a pointer to that.

You might be confused because of devs being a pointer-to-pointer. This is because it is actually returning a pointer to an array, but since you are not even using that in your code, I would forget about it for now.

  1. The syntax of libusb_strerror() is const char * libusb_strerror (int errcode). The function returns constant string. Should I declare a char or char array or string to read the returned value?

You should declare a variable exactly the same as the return type of libusb_strerror(), thus:

const char *err_string;
err_string = libusb_strerror(rc);

If the returned value is a string, then how can a characer pointer hold it?

The returned value is a pointer, you just make a copy of the pointer. The pointer points to some part of memory where the string is stored. You don't have to worry about how libusb allocated it.

  1. I can open the device. But the bulk transfer command returns 5 and fails. I am not sure at which part I am making mistake.

The code looks mostly fine, except you want to call libusb_strerror() after the second call to libusb_bulk_transfer(), not right before it. Error code -5 is LIBUSB_ERROR_NOT_FOUND. This might mean it didn't find the endpoint. Are you sure IN_EP and OUT_EP are set correctly?

G. Sliepen
  • 7,637
  • 1
  • 15
  • 31