首页 > 解决方案 > 在 libusb_fill_interrupt_transfer 回调中使用“user_data”时出错

问题描述

我正在使用 libusb-1.0 将 BLE 加密狗与 RCU 配对。

为此,我成功地向加密狗接口写入了配对请求。为了收听加密狗响应,我使用了该函数libusb_fill_interrupt_transfer并传递了一个回调,该回调将在接收到响应时执行。此函数接受一个参数,如文档 ( void *user_data) 中所述,可在回调中使用。但是当我尝试使用这个参数时,我得到一个编译错误。

未声明(在此函数中首次使用)

在调用前一个函数和声明我的回调之后:

libusb_fill_interrupt_transfer(pairing->transfer, dctx->devh, 0x84, pairing->buffer,
    sizeof(pairing->buffer), cb_aknowledgement, pairing, 0);

static void cb_aknowledgement(struct libusb_transfer *transfer)
{
    if (pairing->transfer->status != LIBUSB_TRANSFER_COMPLETED) {
        printf( "img transfer status %d?\n", pairing->transfer->status);
        libusb_free_transfer(pairing->transfer);
        pairing->transfer = NULL;
        return;
    }

    if(pairing->buffer[0]!=0x05 || pairing->buffer[1]!=0x21)
    {
        printf( "wrong command recieved\n");
        libusb_free_transfer(pairing->transfer);
        pairing->transfer = NULL;
        return;
    }

    printf("I've read data  \n");
    printf("USB Report Id           =  0x%x \n",pairing->buffer[0]);
    printf("Command                 =  0x%x \n",pairing->buffer[1]);
    printf("Acknowledgement type    =  0x%x \n",pairing->buffer[2]);
    return ;
}

问题是:如何使用user_dataI 作为参数传递给回调?

标签: clibusblibusb-1.0

解决方案


使用transfer->user_data. 来自libusb_transfer 结构文档

数据字段
void * user_data
要传递给回调函数的用户上下文数据。

我不知道是什么类型,pairing但它看起来像这样:

int main() {
   ...
   struct pairing_type_s *pairing = pairing_init();
   ...
   libusb_fill_interrupt_transfer(pairing->transfer, dctx->devh, 0x84, pairing->buffer,
    sizeof(pairing->buffer), cb_aknowledgement, pairing, 0);
    ...
}

// Then later:

static void cb_aknowledgement(struct libusb_transfer *transfer)
{
     assert(transfer != NULL);
     struct pairing_type_s *pairing = transfer->user_data;
     assert(pairing != NULL);
     // use pairing like a pro
     ...
}

但是,如果您确保始终使用 with 和使用宏调用,您也libusb_fill_interrupt_transfer可以pairing->transfercb_aknowledgement专业container_of

int main() {
   ...
   struct pairing_type_s *pairing = pairing_init();
   ...
   libusb_fill_interrupt_transfer(pairing->transfer, dctx->devh, 0x84, pairing->buffer,
    sizeof(pairing->buffer), cb_aknowledgement, NULL, 0);
    ...
}

// Then later:

static void cb_aknowledgement(struct libusb_transfer *transfer)
{
     assert(transfer != NULL);
     struct pairing_type_s *pairing = container_of(transfer, struct pairing_type_s, transfer);
     assert(pairing != NULL);
     // use pairing like a pro
     ...
}

但在这种情况下,我更喜欢第一种方法,因为它更具可读性且更无错误。


推荐阅读