2

ZMQ 経由でかなり大きな Flatbuffers オブジェクトをネットワーク経由で送信し、C++ を使用して読み取ろうとしています。オブジェクトにアクセスすると、解決方法がわからない未処理の例外が発生します。この最小限の例でさえ失敗します:

フラットバッファスキーマ:

namespace flatbuffer;
table TestBuf {
  testStatus:bool;
  testNumber:double;
  testInt:int;
}
root_type TestBuf;

REP ソケットを使用する main.cpp:

int main() {
    zmq::context_t context(1);
    zmq::socket_t socket(context, ZMQ_REP);
    socket.bind("tcp://*:5555");

    std::cout << "Listening for requests." << std::endl;
    std::cout << "-----" << std::endl;

    double count = 0;
    while (1) {
        zmq::message_t request;
        socket.recv(&request);

        // Read incoming data
        auto reqmsg = flatbuffer::GetTestBuf(&request);
        std::cout << "Received: " << reqmsg << std::endl;

        flatbuffers::FlatBufferBuilder fbb;
        flatbuffer::TestBufBuilder builder(fbb);

        count++;
        builder.add_testNumber(count);      
        std::cout << "Sending " << count << std::endl;

        auto response = builder.Finish();
        fbb.Finish(response);

        // Send the flatbuffer
        int buffersize = fbb.GetSize();
        zmq::message_t message(buffersize);
        memcpy((void *)message.data(), fbb.GetBufferPointer(), buffersize);
        socket.send(message);
    }
    return 0;
}

REQ ソケットを使用する main.cpp:

int main() {
    // Prepare ZMQ context and socket
    zmq::context_t context(1);
    zmq::socket_t socket(context, ZMQ_REQ);
    std::cout << "Sending out data requests." << std::endl;
    socket.connect("tcp://localhost:5555");

    double count = 0;
    while (1) {
        // Formulate response
        flatbuffers::FlatBufferBuilder fbb;
        flatbuffer::TestBufBuilder builder(fbb);

        count++;
        builder.add_testNumber(count);
        auto response = builder.Finish();
        fbb.Finish(response);

        // Send the flatbuffer
        std::cout << "Sending. " << count << ". ";
        int buffersize = fbb.GetSize();
        zmq::message_t message(buffersize);
        memcpy((void *)message.data(), fbb.GetBufferPointer(), buffersize);
        socket.send(message);
        std::cout << "Sent. ";

        // Receive reply
        zmq::message_t reply;
        socket.recv(&reply);

        // Read the data
        auto inmsg = flatbuffer::GetTestBuf(&reply);
        std::cout << " Received reply: " << inmsg << std::endl;

        //auto num = inmsg->testNumber();
        //std::cout << num << " test number.";
    }
    return 0;
}

このコードは正常に実行され、各プログラムが受信している生のバッファが表示されます (私はそう思います)。不思議なことに、メッセージの内容は変わらないはずなのに、変わっていません。最後の 2 行のコメントを外して inmsg->testNumber() にアクセスしようとすると、次のエラー メッセージが表示されます。

Unhandled exception at 0x000000013F373C53 in KUKAREQ.exe: 0xC0000005: Access violation reading location 0x00000000004B35D8.

以前に ZMQ を介して Flatbuffers オブジェクトを正常に送信したことがありますが、C++ でそれらを読み取ったことはありません。私はFlatbuffers のチュートリアルに厳密に従ったと確信していますが、明らかに何かがおかしくなっています。ポインタ?バッファサイズ?いずれにせよ、助けていただければ幸いです。


編集:受け入れられた回答に対する私のコメントを明確にするために、問題のある行は次のとおりです。

auto inmsg = flatbuffer::GetTestBuf(&reply);

次のように変更する必要があります。

auto inmsg = flatbuffer::GetTestBuf(reply.data());

この質問を読んだ人は誰でも、後で FlatBufferBuilder 関数が正しい順序で呼び出されないときに発生するバグに遭遇したことを知りたいと思うかもしれません。Flatbuffers オブジェクトが構築される順序は明らかに重要です。それを見つけるのにしばらく時間がかかりました-初心者は気をつけてください。

4

1 に答える 1