首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通过boost消息队列发送复杂数据结构

通过boost消息队列发送复杂数据结构
EN

Stack Overflow用户
提问于 2012-09-10 15:05:23
回答 2查看 10.8K关注 0票数 10

我有以下数据结构:

代码语言:javascript
运行
复制
typedef struct
{
    short id;
    string name;
    short age;
} person_struct;

使用boost message queue,我尝试将此数据结构发送到另一个进程中的消息队列接收器。然而,在接收之后,我在访问上述结构中的'name‘变量时出现了分段错误。

下面是我的发送者函数:

代码语言:javascript
运行
复制
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);

下面是我的接收器函数:

代码语言:javascript
运行
复制
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出现分段错误。在某处读到我需要为结构做序列化,但不知道如何做。有没有人能提个建议?

EN

回答 2

Stack Overflow用户

发布于 2012-09-10 18:30:02

boost doc for message queue

消息队列只在进程之间复制原始字节,而不发送对象。这意味着,如果我们想要使用消息队列发送对象,该对象必须是二进制可序列化的。例如,我们可以在进程之间发送整数,但不能发送std::string。您应该使用Boost.Serialization或使用高级Boost.Interprocess机制在进程之间发送复杂数据。

使用Boost.Serialization序列化您的对象,并在接收端反序列化。

一些快速有效的代码:

info.hpp

代码语言:javascript
运行
复制
#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

代码语言:javascript
运行
复制
#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

代码语言:javascript
运行
复制
#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");
}
票数 18
EN

Stack Overflow用户

发布于 2014-11-04 06:28:09

传输复杂数据结构的一种方法是采用传统的方式--制作自己的数据编码器/解码器。如果您使用ASN1 (抽象语法表示法一)的基本概念,那么您可以将数据编码为二进制字段,然后使用解码器传输和解码它

/*示例:创建要发送到服务器的事件消息,要求服务器使用方法MusicPlayer传递事务id和操作开始/停止所有数据都在pCompressedData中!应该发送就是这个内存。

代码语言:javascript
运行
复制
 // 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格式

代码语言:javascript
运行
复制
 // 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解决方案的基本宏!

ASN1 info

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12346787

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档