【问题标题】:C++ Segmentation fault - messages between 2 applicationsC++ 分段错误 - 2 个应用程序之间的消息
【发布时间】:2016-11-18 08:46:12
【问题描述】:

我有 2 个不同的应用程序,一个发送者和一个接收者。发送者将向接收者发送消息,接收者将解码消息并打印到控制台。但是,我不断收到分段错误错误。

发送方和接收方应用程序具有相同的 TestContainer.h 和 TestContainer.cpp。

铸造方法

template<class To,class From>To cast(From v)
{
        return static_cast<To>(static_cast<const void*>)(v);
}

发送者应用程序

int main()
{
    TestContainer tc;
    tc.setDesc("this is a message");
    const char* castedData = cast<const char*>(&tc);

    const TestContainer test_tc = cast<const TestContainer*>(castedData);

    // i get back "this is a message",so the casting is working
    cout << "message content: " << test_tc->getDesc() <<endl;

    TaoSender;      
    TaoSender.send(castedData);     

    return 1;
}

接收方申请

void push(const RtecEventComm::EventSet& events)
{
    const char* receivedData;
    events[0].data.any_value >>= receivedData;

    cout << "data received: " << receivedData << endl;

    const TestContainer rcv_tc = cast<const TestContainer*>(receivedData);

    cout << "message content: " << rcv_tc->getDesc() <<endl; // error(segmentation fault)
}

TestContainer.h 和 TestContainer.cpp

class TestContainer{
    public 
        TestContainer();
        virtual ~TestContainer();
        const std:string& getDesc () const {
            return desc;
        }
        void setDesc(const std::string& desc) {
            this->desc = desc;
        }
    private
        std::string desc;
}



#include TestContainer.h

TestContainer::TestContainer(){}
TestContainer::~TestContainer(){}

发送方castedData的值和接收方receivedData的值是一样的,所以我猜消息发送是正确的。

但是,在 Receiver 处,在将 receivedData 缓冲区转换为 Testcontainer 指针并尝试访问 desc 后,我收到分段错误错误。

我还尝试在 Sender 中强制转换回 Testcontainer,并且可以访问 desc。那么我错过了什么?

【问题讨论】:

  • 你不应该转换数据,你把一个 char* 转换成一个类,这是在自找麻烦。
  • 这段代码有基本的语法错误,例如return static_cast&lt;To&gt;(static_cast&lt;const void*)(v); - 缺少“>”和放错位置的括号。请在自包含示例中发布实际代码 (minimal reproducible example)。
  • 这看起来一点也不像 CORBA 程序,请查看 TAO 中的示例和测试
  • @JohnnyWillemsen TAO RtecEvent 发送和接收服务是我自己封装的,所以如果我发送一个简单的字符串、浮点数或整数值,接收者可以完美地接收到该值,因此消息传递服务正在工作。但是,如果我想发送一个类(属性值的集合),我应该如何发送它?我确实有 40 多个课程,所以我希望有一种简单的方法可以转换为数据流。
  • 您必须自己将数据放入例如 CORBA Any 并发送。你只是不能强制转换一个类,TAO 不知道如何将你的类型编组为有线表示。

标签: c++ segmentation-fault message corba tao


【解决方案1】:

虽然您问题中的代码包含错误,但如果我理解正确,您正试图通过管道或其他通道将对象的表示推送到另一个进程,在那里您重建对象并尝试使用它。

您可以使用“Plain Old Data”对象执行此操作,但TestContainer 类具有虚拟方法,因此它不是 POD。在大多数 C++ 实现中,TestContainer 类型的对象将包含一个 vtable 指针,该指针指向在进程地址空间内分配的表。这个表的地址在不同的进程中可能会有所不同。因此,当您尝试调用虚拟方法时,将TestContainer 对象的表示逐字节复制到另一个进程会导致崩溃。

TestContainer 实例还包含一个std::stringstring 分配存储空间来保存字符串内容,并且该存储空间将位于对象本身之外。将string 的字节表示作为TestContainer 的一部分传输会导致string 的另一端重建,该string 保存指向另一个进程中的内存地址的指针。在接收器中,该内存地址将引用其他内容。因此,string 将无法成功重构。

要在进程之间发送对象,您需要以独立于其中包含的内存地址的形式正确传输它们(无论是 vtable 指针、指针成员还是不透明成员的指针成员,例如 @ 987654331@)。将数据转换为这种形式的过程称为序列化。有一些库可以帮助解决这个问题,但标准库中没有。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    • 2023-03-19
    相关资源
    最近更新 更多