#qt
#qt
Вопрос:
Можем ли мы отправить структуру, содержащую указатели на другие структуры, через сокет QTcpSocket в сокет QTcpServer программы, запущенной в другом физическом расположении, чем эта программа. Мой код будет выглядеть следующим образом….
<i>
QTcpSocket tcpSocket = new QTcpSocket(this);
Struct a{ int a1; int a2;} __attribute__((packed));
Struct b { int b1; int b2}__attribute__((packed));
Struct c{ a *c1; a*c2; }QByteArray block;
QDataStream out(amp;block, QIODevice::WriteOnly);
out << quint16(0)<<c;
out << quint16(block.size() - sizeof(quint16));
tcpSocket->write(block);
</i>
но при этом возникает ошибка, подобная:
/TcpClient-build-desktop/../TcpClient/tcpclient.cpp:137: ошибка: нет соответствия для ‘operator<<’ in ‘out.QDataStream::operator<<(0) << c’
Ответ №1:
Вы можете, если получатель знает, что он не может иметь только указатели, разыменованные процессом отправки. Это означало бы обратную связь с источником и ожидание результата. Этот процесс называется «брокинг объектов» и был реализован, например, в CORBA, COM , jre и других.
Указатель должен интерпретироваться только в известной части виртуальной памяти.
Комментарии:
1. Спасибо. вы имеете в виду, что после отправки пакета TCP отправляющая машина также отправит фактические данные, на которые указывают указатели …?
2. @anjali: возможно, по запросу. Суть в том, что получатель должен рассматривать «указатели» как дескрипторы объектов, которые он не может разрешить сам.
Ответ №2:
Конечно, вы можете, но это не имело бы особого смысла. 🙂 Если в структуре есть указатели, то они будут недействительны на удаленном хосте.
Конечно, вы могли бы дополнительно отправить то, на что указывают указатели, если вам это нужно.
Один совет: если вы программируете для переносимости, не забудьте преобразовать любые целые числа в сетевой порядок байтов перед передачей, а затем обратно в порядок байтов хоста.
Комментарии:
1. @anjali Я никогда не видел
attribute((packed))
синтаксиса. Это какое-то расширение C ?2. _attribute_((упакованный)) , сообщает gcc, чтобы исключить все дополнения между элементами.
3. @anjali Хорошо. Это не поможет вам в этом вопросе. Я думаю, вам следует рассмотреть то, что предлагает Дариуш Шарсиг, использовать сериализацию. И, затем, преобразование любых целых чисел.
Ответ №3:
В дополнение к тому, что было сказано, вы также могли бы использовать подход, аналогичный подходу системы RPC, которая также отправляет объект, на который указывают эти указатели, но сохраняет их в куче и соответствующим образом изменяет указатели на принимающей машине, таким образом, вы действительно получаете указатели, которые работают. Выполнить это без ошибок, конечно, непросто, и вы должны использовать этот подход, только если невозможно изменить вашу концепцию.
С наилучшими пожеланиями
D
Комментарии:
1. Спасибо. Если я правильно вас понимаю, во время отправки фактически поток фактических данных должен быть отправлен тому, на кого указывают указатели?? В QTcpSocket мы добавляем любой объект, такой как блок QByteArray; QDataStream out(amp;block, QIODevice::WriteOnly); out << quint16(0) <<ObjectStructureToSend; out.device()-> seek(0); TCPSocket-> write(блок); итак, как преобразовать фактические данные перед отправкой?
2. Да, именно. Вы перезаписали оператор << в своем
ObjectStructureToSend
и отправляете туда не сам указатель (что бесполезно, поскольку он содержит адрес в памяти отправляющих машин), а сериализацию структуры, на которую указывает указатель. С другой стороны, при десериализации вы берете эти «данные указателя», создаете объект в куче и устанавливаете указатель на этот адрес.
Ответ №4:
Вы можете использовать Qxt, который имеет механизм RPC в своем сетевом модуле. Вы можете подключать сигналы и слоты через сеть и отправлять объекты произвольных типов в качестве аргументов. Вы можете получить ее здесь.