Как использовать libusb и libusb_get_device_descriptor()?

Я впервые учусь использовать libusb v1.0.0 в Ubuntu 12.10. Вот небольшой тестовый код, который я использую, чтобы попытаться понять, как использовать этот API:

#include <libusb-1.0/libusb.h>
...
libusb_device **list;
libusb_get_device_list(ctx, &list); // Returns 11 USB devices which is correct.
for (size_t idx = 0; list[idx] != NULL; idx ++)
{
    libusb_device *dev = list[idx];
    libusb_device_descriptor desc = {0};
    int rc = libusb_get_device_descriptor(dev, &desc);

На данный момент rc == 0, что означает, что он должен был завершиться успешно. Источник: документация для *libusb_get_device_descriptor()*.

Но структура desc всегда пуста. Ни одно из полей никогда не устанавливается. Если я изменю последние две строки выше на это:

    libusb_device_descriptor desc = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int rc = libusb_get_device_descriptor(dev, &desc);

... затем, когда libusb_get_device_descriptor() возвращается, я вижу, что desc остается неизменным, подтверждая для меня, что я не получаю того, что ожидаю от этого API.

Я также пытался запустить a.out от имени пользователя root на тот случай, если для этого требуются повышенные привилегии. Поиск в Google по libusb_get_device_descriptor ни к чему не привел.

Соответствующие команды, которые я запускал, чтобы попробовать этот код:

sudo apt-get install libusb-1.0.0-dev
g++ -ggdb test.cpp -lusb-1.0
./a.out 

Ах! Сумасшедшая ошибка пользователя! код шарта помог мне разобраться. Вот код, который я на самом деле использовал — посмотрите, сможете ли вы найти ошибку:

std::cout << "rc == " << libusb_get_device_descriptor(dev, &desc) << std::endl
          << "vendor == " << desc.idVendor << std::endl;

Я предполагаю, что компилятор оценивает это так, что он может свободно оценивать desc.idVendor до того, как вызов libusb_get_device_descriptor() будет фактически сделан. Виноват.


person Stéphane    schedule 06.02.2013    source источник
comment
На самом деле поведение вашего cout было неопределенным. Рад помочь!   -  person Bill Lynch    schedule 06.02.2013


Ответы (3)


Вы не включили полный компилируемый тестовый пример. Так что я построил один. Это работает для меня на CentOS 6 x64. Я также запускаю это как обычную учетную запись пользователя.

Источник

#include <cassert>
#include <cstdio>
#include <libusb-1.0/libusb.h>

int main() {
    libusb_context *context = NULL;
    libusb_device **list = NULL;
    int rc = 0;
    ssize_t count = 0;

    rc = libusb_init(&context);
    assert(rc == 0);

    count = libusb_get_device_list(context, &list);
    assert(count > 0);

    for (size_t idx = 0; idx < count; ++idx) {
        libusb_device *device = list[idx];
        libusb_device_descriptor desc = {0};

        rc = libusb_get_device_descriptor(device, &desc);
        assert(rc == 0);

        printf("Vendor:Device = %04x:%04x\n", desc.idVendor, desc.idProduct);
    }

    libusb_free_device_list(list, count);
    libusb_exit(context);
}

Выход

Vendor:Device = 1d6b:0002
Vendor:Device = 1d6b:0002
Vendor:Device = 8087:0020
Vendor:Device = 8087:0020
Vendor:Device = 0424:2514
Vendor:Device = 10c4:ea60
Vendor:Device = 051d:0002
Vendor:Device = 0624:0248
person Bill Lynch    schedule 06.02.2013
comment
@Йети: Конечно. Не стесняйтесь вносить подобные правки самостоятельно в будущем. - person Bill Lynch; 17.06.2018
comment
libusb_free_device_list (список, количество); void libusb_free_device_list(libusb_device **list, int unref_devices) Освободить список устройств, обнаруженных libusb_get_device_list. Если для параметра unref_device установлено значение 1, счетчик ссылок всех устройств в списке уменьшается один раз. у вас неправильный параметр unref_devices - person Brandon Ros; 06.08.2020

Это не отдельный ответ, это скорее комментарий к сообщению Билла Линча. Я не могу добавить комментарий к сообщению Билла Линча (отсутствует репутация), поэтому я решил сделать это таким образом ;-).

В приведенном выше коде отсутствует небольшая деталь:

вам нужно вручную освободить список, который вы заполнили из libusb_get_device_list.

Из документа libusb:

Ожидается, что вы сбросите ссылки на все устройства, когда закончите с ними, а затем освободите список с помощью libusb_free_device_list(). Обратите внимание, что libusb_free_device_list() может удалить все устройства за вас. Будьте осторожны, чтобы не отменить ссылку на устройство, которое вы собираетесь открыть, до тех пор, пока вы его не откроете.

person lexXxel    schedule 24.03.2016

Просто чтобы добавить к ответу Билла, чтобы избежать многочисленных предупреждений, которые вы, вероятно, получите из этой строки.

libusb_device_descriptor desc = {0};

Просто удалите задание.

libusb_device_descriptor desc;

Ничего страшного, но меня эти вещи беспокоят.

person Goddard    schedule 27.05.2016