Упаковать указатель объекта класса в символ * для очереди сообщений

#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