У меня есть 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 у получателя то же самое, поэтому я думаю, что отправка сообщения правильная.
Однако на Получатель, после преобразования буфера receiveData в указатель Testcontainer и попытки доступа к desc я получаю ошибку ошибки сегментации.
Я также попытался вернуться к Testcontainer в отправитель, и я могу получить доступ к desc. Так что я пропустил?
Хотя код в вашем вопросе содержит ошибки, если я правильно вас понимаю, вы пытаетесь передать представление объекта по каналу или другому каналу другому процессу, где вы восстанавливаете объект и пытаетесь использовать его.
Вы можете сделать это с объектами «Plain Old Data», но TestContainer
класс имеет виртуальные методы и поэтому не является POD. В большинстве реализаций C ++ объекты типа TestContainer
будет содержать указатель vtable, который ссылается на таблицу, размещенную в адресном пространстве процесса. Адрес этой таблицы, вероятно, будет отличаться в разных процессах. Таким образом, копирование представления TestContainer
Объект побайтовый к другому процессу приведет к сбоям при попытке вызвать виртуальный метод.
TestContainer
экземпляры также содержат std::string
, string
выделяет хранилище для хранения содержимого строки, и это хранилище будет вне самого объекта. Передача байтового представления string
как часть TestContainer
приводит к реконструкции на другом конце string
который содержит указатель на адрес памяти в другом процессе. Внутри получателя этот адрес памяти будет ссылаться на что-то еще. Следовательно string
не будет успешно реконструирован.
Чтобы отправлять объекты между процессами, вам нужно правильно передавать их в форме, которая не зависит от адресов памяти, содержащихся в них (будь то указатель vtable, член-указатель или член-указатель непрозрачного элемента, такого как string
). Процесс преобразования данных в такую форму называется сериализацией. Есть библиотеки, которые могут помочь с этим, но ничего в стандартной библиотеке нет.
Других решений пока нет …