libusb
在操作USB相关内容时,有一个比较著名的库就是libusb
。
官方网址:libusb
下载:
- 下载源码
- 官方编好的库
- github:Releases · libusb/libusb (github.com)
使用:libusb: Application Programming Interface (sourceforge.io)
- Functions
- Structures
- Enums
自动刷新程序Code
这里介绍一个基于libusb自动刷新usb的demo。
目录结构
3rdparty
包- libusb的头文件和库
- 这里采用官方编好的现成的库
usb
包- 基于C++对libusb的封装
- 此包为纯C++代码
code
包- 基于Qt的ui和线程
E:.
└─usbReset
│ main.cpp
│ usbReset.pro
│
├─3rdparty
│ └─libusb
│ ├─include
│ │ └─libusb-1.0
│ │ libusb.h
│ │
│ └─MinGW32
│ ├─dll
│ │ libusb-1.0.dll
│ │ libusb-1.0.dll.a
│ │
│ └─static
│ libusb-1.0.a
│
├─code
│ THREAD_TimerUsb.cpp
│ THREAD_TimerUsb.h
│ WIDGET_Main.cpp
│ WIDGET_Main.h
│ WIDGET_Main.ui
│
└─usb
usb.pri
USB_Hotplug.cpp
USB_Hotplug.h
USB_Reset.cpp
USB_Reset.h
Code
项目文件
usbReset.pro
QT += core
QT += widgets
#CONFIG += console
CONFIG += c++17
DESTDIR = $$PWD/bin
include($$PWD/usb/usb.pri)
INCLUDEPATH += $$PWD/code
HEADERS += \
code/THREAD_TimerUsb.h \
code/WIDGET_Main.h
SOURCES += \
main.cpp \
code/THREAD_TimerUsb.cpp \
code/WIDGET_Main.cpp
FORMS += \
code/WIDGET_Main.ui
usb/usb.pri
# 链接到libusb(采用静态库)
INCLUDEPATH += $$PWD/../3rdparty/libusb/include
HEADERS += $$PWD/../3rdparty/include/libusb/libusb-1.0/libusb.h
LIBS += -L$$PWD/../3rdparty/libusb/MinGW32/static/ -llibusb-1.0
# 当前封装的包
INCLUDEPATH += $$PWD/..
HEADERS += \
$$PWD/USB_Hotplug.h \
$$PWD/USB_Reset.h
SOURCES += \
$$PWD/USB_Hotplug.cpp \
$$PWD/USB_Reset.cpp
main.cpp
#include <QApplication>
#include "WIDGET_Main.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MainWidget form;
form.show();
return app.exec();
}
usb
包
USB_Reset.h
#ifndef MYUSB_H_1682212693
#define MYUSB_H_1682212693
extern "C" {
#include "libusb-1.0/libusb.h"
}
#include <string>
#include <vector>
namespace USB {
class Reset final {
public:
inline static const int EMPTY_POINTER_INT = 114514;
private:
/// for init & exit
static libusb_context* context;
static uint32_t obj_count;
public:
static int Reset_context();
private:
char str[1024]{
};
public:
/// libusb_init()
Reset();
/// libusb_exit()
~Reset();
public:
::std::vector<::std::string> Show_device();
public:
libusb_device_descriptor Find_descriptByidVendor(uint32_t Vendor);
public:
/**
* vendor -> device* -> handle*
* handle* -> reset
* handle* -> close
*/
libusb_device* Find_deviceByidVendor(uint32_t Vendor);
libusb_device_handle* Get_handleByOpenDevice(libusb_device* device);
int Reset_usbByHandle(libusb_device_handle* device_handle);
void Close_deviceByHandle(libusb_device_handle* device_handle);
};
} // namespace USB
#endif // MYUSB_H_1682212693
USB_Reset.cpp
#include "USB_Reset.h"
namespace USB {
/**
* @brief UsbBase::context
* static data
* context: 所有对象共享这一个全局的上下文对象
* obj_count: 引用计数
*/
libusb_context* Reset::context = nullptr;
uint32_t Reset::obj_count = 0;
/**
* @brief UsbBase::Reset_context
* @return
* static 重置上下文
*/
int Reset::Reset_context() {
/// 有实体对象才重置 context
if (0 != obj_count) {
if (nullptr != context) {
libusb_exit(context);
context = nullptr;
}
return libusb_init(&context);
}
return LIBUSB_SUCCESS;
}
/**
* @brief UsbBase::UsbBase
* constructor
* 上下文的init
* 维护引用计数
*/
Reset::Reset() {
/// 查看版本号
const struct libusb_version* version = libusb_get_version();
printf(">>>Libusb-Version:%s\n", version->describe);
printf(">>>Libusb-Version:%d.%d.%d.%d\n",
version->major,
version->minor,
version->micro,
version->nano
);
/// 第一个对象,或者之前没有注册成功
if (0 == obj_count || nullptr == context) {
if (int res = libusb_init(&context); res != 0) {
sprintf(str, "fail to init: %d\n", res);
/// TODO
/// 根据实际情况,日志、断言、异常等
/// TODO
}
}
obj_count += 1;
}
/**
* @brief UsbBase::~UsbBase
* distructor
* 维护引用计数
* 上下文的退出
*/
Reset::~Reset() {
obj_count += -1;
if (0 == obj_count) {
if (nullptr != context) {
libusb_exit(context);
context = nullptr;
}
}
}
/**
* @brief UsbBase::show_device
* just show device-list message
*/
::std::vector<::std::string> Reset::Show_device() {
::std::vector<::std::string> messageList;
messageList.push_back(
"********************** show device-list message BEGIN "
"**********************");
/// help data
libusb_device** deviceList = nullptr;
libusb_get_device_list(nullptr, &deviceList);
for (int i = 0; deviceList[i] != nullptr; i += 1) {
auto device = deviceList[i];
struct libusb_device_descriptor descript;
int ret = libusb_get_device_descriptor(device, &descript);
if (LIBUSB_SUCCESS != ret) {
continue;
}
sprintf(str,
"*"
"idVendor:%6d "
"idProduct:%6d "
"bDeviceClass:%6d "
"(bus:%3d, device:%3d)"
"*",
descript.idVendor, descript.idProduct, descript.bDeviceClass,
libusb_get_bus_number(device),
libusb_get_device_address(device));
messageList.push_back(str);
}
messageList.push_back(
"********************** show device-list message END "
"************************");
return messageList;
}
/**
* @brief MyUsb::Find_descriptByidVendor
* @param idVendor
* @return
* 获取设备描述对象
*/
libusb_device_descriptor Reset::Find_descriptByidVendor(uint32_t idVendor) {
/// ret
libusb_device_descriptor descriptor;
/// help data
libusb_device_handle* deviceHandle = nullptr;
libusb_device** deviceList = nullptr;
libusb_get_device_list(nullptr, &deviceList);
for (int i = 0; deviceList[i] != nullptr; i += 1) {
auto device = deviceList[i];
int ret = libusb_get_device_descriptor(device, &descriptor);
if (LIBUSB_SUCCESS != ret) {