我有以下数据结构:
typedef struct
{
short id;
string name;
short age;
} person_struct;
使用boost消息队列,我试图在另一个进程中将此数据结构发送到消息队列接收器。但是,收到后,我在访问上述结构中的'name'变量时出现了分段错误。
以下是我的发件人功能:
person_struct MyRec;
MyRec.id = 1;
MyRec.name = "ABC123";
MyRec.age = 20;
message_queue mqSender(create_only, "MSG_Q", 100, sizeof(person_struct));
mqSender.send(&MyRec, sizeof(person_struct), MQ_PRIORITY);
以下是我的接收器功能:
message_queue myReceiver(open_only, "MSG_Q");
person_struct *recvMsg = new person_struct();
size_t msg_size;
unsigned int priority;
myReceiver.receive(recvMsg, sizeof(person_struct), msg_size, priority);
cout << "ID: " << (*recvMsg).id << endl;
cout << "Name: " << (*recvMsg).name << endl;
cout << "Age: " << (*recvMsg).age << endl;
(* recvMsg).id的cout没问题,但在(* recvMsg).name的cout上发生了分段错误。阅读我需要为结构进行序列化的地方,但无法弄清楚如何去做。有人可以建议吗?
答案 0 :(得分:13)
来自boost doc for message queue:
消息队列只是在进程之间复制原始字节而不发送对象。这意味着如果我们想要使用消息队列发送对象,则该对象必须是二进制可序列化的。例如,我们可以在进程之间发送整数,但不能在std :: string之间发送整数。您应该使用Boost.Serialization或使用高级Boost.Interprocess机制在进程之间发送复杂数据。
使用Boost.Serialization序列化您的对象并在接收端反序列化。
一些快速,有效的代码:
<强> info.hpp 强>
#include <boost/serialization/string.hpp>
#define MAX_SIZE 1000
class info
{
public:
info (int i = 0, std::string n = "")
: id(i), name(n)
{};
int id;
std::string name;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & id;
ar & name;
}
};
<强> send.cpp 强>
#include <string>
#include <sstream>
#include <boost/interprocess/ipc/message_queue.hpp>
#include <boost/archive/text_oarchive.hpp>
#include "info.hpp"
using namespace boost::interprocess;
int main ()
{
try
{
message_queue mq
(
open_or_create,
"mq",
100,
MAX_SIZE
);
info me(1, "asdf");
std::stringstream oss;
boost::archive::text_oarchive oa(oss);
oa << me;
std::string serialized_string(oss.str());
mq.send(serialized_string.data(), serialized_string.size(), 0);
}
catch(interprocess_exception &ex)
{
std::cerr << ex.what() << std::endl;
}
}
<强> receive.cpp 强>
#include <string>
#include <iostream>
#include <boost/interprocess/ipc/message_queue.hpp>
#include <boost/archive/text_iarchive.hpp>
#include "info.hpp"
using namespace boost::interprocess;
int main ()
{
try
{
message_queue mq
(
open_only,
"mq"
);
message_queue::size_type recvd_size;
unsigned int priority;
info me;
std::stringstream iss;
std::string serialized_string;
serialized_string.resize(MAX_SIZE);
mq.receive(&serialized_string[0], MAX_SIZE, recvd_size, priority);
iss << serialized_string;
boost::archive::text_iarchive ia(iss);
ia >> me;
std::cout << me.id << std::endl;
std::cout << me.name << std::endl;
}
catch(interprocess_exception &ex)
{
std::cerr << ex.what() << std::endl;
}
message_queue::remove("mq");
}
答案 1 :(得分:0)
传输复杂数据结构的一种方法是以旧方式进行 - 制作您自己的数据编码器/解码器。 如果您使用ASN1(抽象语法表示法一)的基本概念,那么您可以将数据编码为二进制字段,然后传输它并使用您的解码器解码它
/ *示例:创建要发送到服务器的事件消息,要求其使用方法MusicPlayer 传递事务ID和操作Start / Stop 所有数据都在pCompressedData中!应该发送这个内存。
// Client code
// Create DataEncoderDecoder response
// Encode
DED_START_ENCODER(encoder_ptr);
DED_PUT_STRUCT_START( encoder_ptr, "event" );
DED_PUT_METHOD ( encoder_ptr, "name", "MusicPlayer" );
DED_PUT_USHORT ( encoder_ptr, "trans_id", trans_id);
DED_PUT_BOOL ( encoder_ptr, "startstop", action );
DED_PUT_STRUCT_END( encoder_ptr, "event" );
DED_GET_ENCODED_DATA(encoder_ptr,data_ptr,iLengthOfTotalData,pCompressedData,sizeofCompressedData);
//要发送的数据在pCompressedData
中 // Server code
// retrieve data ...
//...
std::string strName,strValue;
unsigned short iValue;
bool bValue;
DED_PUT_DATA_IN_DECODER(decoder_ptr,pCompressedData,sizeofCompressedData);
// decode data ...
if( DED_GET_STRUCT_START( decoder_ptr, "event" ) &&
DED_GET_METHOD ( decoder_ptr, "name", strValue ) &&
DED_GET_USHORT ( decoder_ptr, "trans_id", iValue) &&
DED_GET_BOOL ( decoder_ptr, "startstop", bValue ) &&
DED_GET_STRUCT_END( decoder_ptr, "event" ))
{
TRACE0(_T("FAIL!!!\n"));
}
else
{
TRACE0(_T("SUCCESS!!!\n"));
}
*/
创建DED_xxx作为捆绑ASN1解决方案的基本宏!