#c #linux #message-queue #reinterpret-cast #static-cast
#c #linux #очередь сообщений #переинтерпретировать-приведение #статическое приведение
Вопрос:
Возможно ли правильно и безопасно передавать указатель объекта класса через очередь сообщений POSIX?
Например,
Object *obj = new Object();
mq_send(mqdes, static_cast<char*>amp;obj, sizeof(obj), 1);
и на стороне получения выполнить reinterpret_cast
возврат к моему Object
?
Поскольку очереди сообщений используют файловый дескриптор в Linux, мне любопытно, как это работает. Я безуспешно пытался это сделать, но думаю, что, возможно, я делаю что-то не так.
Ответ №1:
Не совсем… только если объект содержит только поля базового типа и другие структуры с полями базового типа. Если вы отправляете указатель, он не может быть повторно использован с другой стороны, если он находится в другом процессе или в другой системе.
Также при использовании классов с наследованием и виртуальных методов может возникнуть беспорядок!
С моей точки зрения, лучше добавить какой-то метод сериализации.
Кроме того, передача двоичного файла struct, сериализованного таким образом, вообще не переносима и может привести к нескольким проблемам, если вы хотите использовать тот же механизм с другими системами или если вы измените структуру или такие вещи, как упаковка объекта.
Пользовательская сериализация десериализация была бы предпочтительнее и более переносима, но выбор, конечно, за вами.
Что-то вроде …
template<typename T>
int SerializeAndSendObject(mqd_t mqdes, const T* instance)
{
MySerializationStream stream;
instance->SerializeTo(stream);
mq_send(stream.toBuffer(), stream.size());
}
Если вы просто отправляете между двумя потоками вместо отправки содержимого объекта, я бы отправил просто указатель на объект, выделенный с помощью new, и я бы освободил его с другой стороны.
Будьте осторожны, чтобы при удалении очереди вы должны были сначала уничтожить все ожидающие объекты!
Object* pointer = amp;obj;
mq_send(mqdes, static_cast<char*>(pointer), sizeof(Object*), 1);
Обратите внимание на sizeof(объект *)… вам нужно отправить только указатель, а не сам объект.
Комментарии:
1. Если вы просто отправляете между двумя потоками вместо отправки содержимого объекта, я бы отправил просто указатель на объект, выделенный с помощью new, и я бы освободил его с другой стороны. Будьте осторожны, чтобы при удалении очереди вы должны были сначала уничтожить все ожидающие объекты!
2. проблема, с которой я сталкиваюсь, заключается в том, что мне нужно ставить события в очередь, и они отправляются через mqueue