3

複数のレポートを HID デバイスから に読み込んでからunsigned char、データを にコピーしようとしていますstd::vector。また、データを 16 進数分析用のファイルに書き込んでいます。その内容は、表示すると正しいように見えます。ただし、std::vectorコンソールにダンプすると、正しいデータが含まれているようには見えません。

これはコードです:

typedef vector<unsigned char> buffer_t;

buffer_t sendCommand (hid_device *devh, const unsigned char cmd[], int reports) {
    unsigned char outbuf[0x40];
    buffer_t retbuf(0x40 * reports);

    hid_write(devh, cmd, 0x41);

    int i;
    FILE *file = fopen("test.out", "w+b");
    while (i++ < reports) {
       hid_read(devh, outbuf, 0x40);
       fwrite(outbuf, 1, sizeof(outbuf), file);
       retbuf.push_back(*outbuf);
    }
    fclose(file);
    cout << &retbuf[0];
    return retbuf;
}

ここで的外れな気がします。私は C/C++ にかなり慣れていないので、しばらくこれに固執しています。誰かが私が間違っていることを教えてくれますか、または私をより良い方向に向けることができますか?

4

5 に答える 5

6

unsigned charベクターに複数のオブジェクトを追加したいのですが、追加できるのpush_backは 1 つだけです。

したがって、retbuf.push_back(*outbuf);次のいずれかに置き換えます。

for (size_t i = 0; i < sizeof(outbuf); ++i) {
    retbuf.push_back(outbuf[i]);
}

また

std::copy(outbuf, outbuf+sizeof(outbuf), std::back_inserter(retbuf));

また

retbuf.insert(retbuf.end(), outbuf, outbuf+sizeof(outbuf));

これらはすべて同じことを行います。

特定のサイズでベクターを作成します。

buffer_t retbuf(0x40 * reports);

ただしpush_back、最後に要素を追加することで、ベクトルのサイズを大きくします。空で作成する必要があります。

buffer_t retbuf;

必要に応じて、ベクターに十分なスペースを割り当てて、追加する要素に備えることができます。

retbuf.reserve(0x40 * reports);

unsigned charこれは純粋にパフォーマンスの問題ですが、ベクトルが内部空間を使い果たし、さらに割り当てる必要がある場合に( とは異なり) コピー/移動するのにコストがかかる大きなベクトル、または型のベクトルでは重大な問題になることがあります。

スタイルに関する注意: リテラル値0x40を数回繰り返し、 も使用しますsizeof(outbuf)。多くの場合、定数を定義し、全体で名前を使用するのが最善です。

const int report_size = 0x40;

これは、将来数値が変更された場合の一部ですが、コードの可読性に関するものでもあります。誰かが見0x40た場合、それが正しい値である理由をすぐに理解できる場合としない場合があります。誰かが見た場合report_size、それが実際にどのような値であるかは調べてみるまでわかりませんが、なぜその値を使用しているのかはわかります。

于 2012-08-29T11:43:07.193 に答える
1

問題は次の行にあります。これは、unsigned char (ゼロ) のデフォルト値で満たされた要素を持つbuffer_t retbuf(0x40 * reports);vector を作成することを意味します。0x40 * reports次にpush_back()、ベクターの最後に新しい要素を追加するだけで、既存の要素には影響しません。

次のように書き直す必要があります。

buffer_t retbuf;                  // Empty vector
retbuf.reserve(0x40 * reports);   // Preallocate memory for known element count

この方法push_back()は期待どおりに機能し、最初から空のベクターに要素を追加します。

outbufもちろん、最初の要素 ( ) だけでなく、のすべての要素を push_back() する必要があります*outbuf

于 2012-08-29T11:45:43.870 に答える
0

ベクトルはunsigned charタイプです。つまり、そのすべての要素がこのタイプです。あなたoutbufはunsignedcharの配列です。

ベクトルのpush_back()最後に1つの項目を追加するだけなので、すべてではなく、push_back(*outbuf)の最初の要素のみをベクトルに追加します。outbuf

すべてのデータをベクターに入れるには、push_back1つずつデータを入れるか、を使用する必要がありますstd::copy

于 2012-08-29T11:42:11.963 に答える
0

outbuf は char 配列であるため、配列/ポインターの二重性により、*outbuf が char 配列の最初の要素になることに注意してください。

あなたはおそらくやりたかったと思います:

typedef vector<string> buffer_t; // alternatively vector<unsigned char*>
...
retbuf.push_back(outbuf);
...

または

typedef vector<unsigned char> buffer_t;
...
for (size_t i = 0; i < sizeof(outbuf); i++)
     retbuf.push_back(outbuf);
...
于 2012-08-29T11:51:39.040 に答える