web-dev-qa-db-ja.com

libusbとlibusb_get_device_descriptor()の使い方は?

私はUbuntu12.10で初めてlibusbv1.0.0を使用することを学んでいます。この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は常に空です。どのフィールドも設定されません。上記の最後の2行をこれに変更すると:

_    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から期待したものが得られていないことを確認できます。

また、昇格された特権が必要な場合に備えて、rootとして_a.out_を実行しようとしました。 _libusb_get_device_descriptor_でGoogle検索を行っても、どこにも行きません。

このコードを試すために実行した関連コマンド:

_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;
_

コンパイラがこれを評価する方法だと思いますが、libusb_get_device_descriptor()の呼び出しが実際に行われる前に、_desc.idVendor_を自由に評価できます。私の悪い。

14
Stéphane

完全なコンパイル可能なテストケースは含まれていませんでした。だから私はそれを作りました。これは、CentOS 6x64で機能します。私もこれを通常のユーザーアカウントとして実行しています。

ソース

#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
28
Bill Lynch

これは独立した答えではなく、BillLynchの投稿へのコメントです。 Bill Lynchの投稿にコメントを追加できない(評判がない)ので、この方法で追加することにしました;-)。

上記のコードには少し詳細が欠けています:

libusb_get_device_listから入力したリストを手動で解放する必要があります。

libusb doc から:

使い終わったら、すべてのデバイスの参照を解除し、libusb_free_device_list()を使用してリストを解放する必要があります。 libusb_free_device_list()は、すべてのデバイスの参照を取り消すことができることに注意してください。開こうとしているデバイスは、開封するまで参照を解除しないように注意してください。

3
lexXxel

ビルの答えに追加するだけで、この行から受け取る可能性のある複数の警告を回避するために

libusb_device_descriptor desc = {0};

割り当てを削除するだけです。

libusb_device_descriptor desc;

大したことではありませんが、これらのことが気になります。

3
Goddard