我有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后,我收到了分段错误。
我还尝试在发件人中转回Testcontainer,我可以访问desc。那么我错过了什么?
答案 0 :(得分:1)
虽然你的问题中的代码包含错误,但如果我理解你正确,你试图通过管道或其他通道将对象的表示推送到另一个进程,在那里重构对象并尝试使用它。
您可以使用&#34; Plain Old Data&#34;对象,但TestContainer
类具有虚方法,因此它不是POD。在C ++的大多数实现中,类型为TestContainer
的对象将包含一个vtable指针,该指针指向在进程中分配的表。地址空间。该表的地址可能在不同的过程中有所不同。因此,当您尝试调用虚方法时,将TestContainer
对象的表示逐字节复制到另一个进程将导致崩溃。
TestContainer
个实例还包含std::string
。 string
分配存储以保存字符串内容,此存储将位于对象本身之外。将string
的字节表示作为TestContainer
的一部分进行传输会导致在string
的另一端重建,该另一端保存指向另一个进程中的内存地址的指针。在接收器内,该内存地址将引用其他内容。因此,string
将无法成功重建。
要在进程之间发送对象,您需要以独立于其中包含的内存地址的形式正确传输它们(无论是vtable指针,指针成员还是不透明成员的指针成员,例如{ {1}})。将数据转换为这种形式的过程称为序列化。有一些库可以帮助解决这个问题,但标准库中没有任何内容。