Я учусь использовать 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()
на самом деле было сделано. Виноват.
Вы не включили полный, компилируемый контрольный пример. Итак, я построил один. Это работает для меня на 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 document:
От вас ожидают, что вы отошлите все устройства после завершения работы с ними, а затем освободите список с помощью libusb_free_device_list (). Обратите внимание, что libusb_free_device_list () может отменить все устройства для вас. Будьте осторожны, чтобы не ссылаться на устройство, которое вы собираетесь открыть, до тех пор, пока вы его не откроете.
Просто добавьте к ответу Билла, чтобы избежать множества предупреждений, которые вы, вероятно, получите от этой строки
libusb_device_descriptor desc = {0};
Просто удалите назначение.
libusb_device_descriptor desc;
Ничего страшного, но эти вещи меня беспокоят.