【发布时间】:2018-12-13 12:00:12
【问题描述】:
我正在编写一个简单的库,它使用libusb 连接到我的自定义硬件,该硬件每 50 毫秒向主机设备发送一次信号。它旨在提供一个简单的抽象层,这样用户就不会被libusb 所困扰。我需要将指向非静态类成员函数的指针传递给libusb_fill_bulk_transfer。 IE。我需要对 MyDevice 的每个实例都有一个单独的回调,而不会将 libusb 逻辑暴露给我的用户。
基本设计是:
-
初始化库
int mylib_init(){ libusb_init(&context); } -
查找所有兼容设备
int mylib_get_valid_devices(vector devs){ //... libusb_device **devs1; int countAll = libusb_get_device_list(context, &devs1); //... 填充开发者 } int mylib_print_device_info(MyDevice* dev); -
连接到用户喜欢的任意数量的设备
int mylib_init_device(MyDevice* dev){ libusb_open(dev->device, &dev->dev_handle); // 检查内核驱动程序并在需要时删除 libusb_claim_interface(dev->dev_handle, 0); //... } -
为所有连接设备实例的传入数据设置回调
int mylib_start_transmission_async(MyDevice* dev, MyLibCallbackIn user_cb, unsigned char* buffer_in, int bufferSize){ libusb_control_transfer(dev->dev_handle, p1, p2, p3, p4, p5, p6, p7); // .. libusb_control_transfer -s 的其余部分 //启动设备: 诠释实际; 无符号字符 startSig = 0b00110111; libusb_bulk_transfer(dev->dev_handle, (1 | LIBUSB_ENDPOINT_OUT), &tosend, 1, &actual, 100); dev->user_callback = user_cb; 开发->buffer_in = buffer_in; 开发->缓冲区大小 = 缓冲区大小; //设置传输 dev->transfer_in = libusb_alloc_transfer(0); libusb_fill_bulk_transfer(dev->transfer_in,dev->dev_handle,LIBUSB_ENDPOINT_IN,dev->buffer_in,dev->bufferSize,cb_in,NULL,0); libusb_submit_transfer(dev->transfer_in); } -
完成后断开
int mylib_disconnect_device(MyDevice* device); -
退出库
int mylib_exit();
MyDevice 定义为:
typedef int (*MyLibdCallbackIn)(unsigned char* buffer, int length);
class MyDevice{
unsigned char* buffer_in;
unsigned char* buffer_out;
libusb_device* device = nullptr;
libusb_device_handle* dev_handle = nullptr;
struct libusb_transfer* transfer_in = nullptr;
struct libusb_transfer* transfer_out = nullptr;
//this obviously wouldn't work because libusb doesn't accept it as a param:
void LIBUSB_CALL cb_in(struct libusb_transfer* transfer);
MyLibCallbackIn user_callback;
void run();
//...
}
而cb_in定义为:
void LIBUSB_CALL MyDevice::cb_in(libusb_transfer* transfer){
int r = libusb_submit_transfer(this->transfer_in);
callback_in(transfer->buffer, transfered);
}
我无法将MyDevice::cb_in 传递给libusb_fill_bulk_transfer,因为函数指针类型不兼容。同时我不希望我的用户必须编写一个以libusb_transfer*为参数的回调函数(暴露给libusb)直接传递给libusb_fill_bulk_transfer。
编辑: 我试过了
void LIBUSB_CALL callback_wrapper(struct libusb_transfer* transfer){
MyDevice* dev = reinterpret_cast<MyDevice*>(transfer->user_data);
dev->cb_in(transfer);
}
但得到Sementation fault (Core dumped) 错误
【问题讨论】:
-
查看
user_data参数的说明。使用它将this传递给静态回调函数,该函数将其转换回对象指针,然后调用类方法。 -
关于您的编辑:您是否将
dev作为用户数据传递?您前面的代码仍然将void* user_data参数显示为NULL,这肯定会给您带来段错误...另外,请确保在回调发生时有问题的设备对象仍然存在(而不仅仅是它的副本) . -
是的,做到了。赞!
标签: c++ libusb member-function-pointers