Как использовать libusb и libusb получить дескриптор устройства ()?

Я учусь использовать 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 

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

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

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

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

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

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

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

с libusb docu:

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


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

libusb_device_descriptor desc = {0};

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

libusb_device_descriptor desc;

не очень много, но эти вещи беспокоят меня.