[英]Reading Flatbuffers objects sent via ZMQ in C++ throws unhandled exception
我正在嘗試通過 ZMQ 通過網絡發送一個相當大的 Flatbuffers 對象,然后使用 C++ 讀取它。 訪問對象時,我遇到了未處理的異常,我不知道如何解決。 即使這個最小的例子也失敗了:
flatbuffers 架構:
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;
}
這段代碼運行良好並顯示(我認為)每個程序正在接收的原始緩沖區。 奇怪的是,它並沒有改變,盡管消息的內容應該改變。 如果我取消對最后兩行的注釋並嘗試訪問 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 對象的構建順序很重要。 找到那個花了我一段時間 - 新手要小心。
不熟悉 ZeroMQ,但flatbuffer::GetTestBuf(&request)
這看起來有問題..你需要傳遞緩沖區,而不是消息結構。 可能request.data()
或類似的效果更好。
通常,如果它在 FlatBuffers 中崩潰,您應該使用驗證器來驗證您傳遞給 FlatBuffers 的緩沖區。 如果失敗,則意味着您沒有將合法數據傳遞給 FlatBuffers,就像這里的情況一樣。
此外,您可能想檢查 ZeroMQ 是否可以在不復制的情況下發送緩沖區,這樣會更快。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.