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

Можно ли правильно и безопасно передать указатель объекта класса через очередь сообщений POSIX?

Например,

Object *obj = new Object();

mq_send(mqdes, static_cast<char*>&obj, sizeof(obj), 1);

а на принимающей стороне выполнить reinterpret_cast обратно к моему Object?

Поскольку очереди сообщений используют дескриптор файла в Linux, мне любопытно, как это работает. Я пробовал это безуспешно, но думаю, что я делаю что-то не так.


person Community    schedule 21.10.2011    source источник


Ответы (1)


Не совсем... только если объект содержит только поля базового типа и другие структуры с полями базового типа. Если вы отправляете указатель, его нельзя повторно использовать с другой стороны, если он находится в другом процессе или в другой системе.

Кроме того, используя классы с наследованием и виртуальными методами, это может привести к беспорядку!

С моей точки зрения, лучше добавить своего рода метод Serialize.

Кроме того, передача бинарной структуры, сериализованной таким образом, вообще не является переносимой и может привести к нескольким проблемам, если вы хотите использовать тот же механизм с другими системами или если вы изменяете структуру или такие вещи, как упаковка объекта.

Пользовательская сериализация\десериализация была бы предпочтительнее и более переносимой, но выбор, конечно, за вами.

Что-то вроде ...

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 = &obj;
mq_send(mqdes, static_cast<char*>(pointer), sizeof(Object*), 1);

Обратите внимание на sizeof(Object*)... вам нужно отправить только указатель, а не сам объект.

person Salvatore Previti    schedule 21.10.2011
comment
Если вы просто отправляете между двумя потоками вместо отправки содержимого объекта, я бы отправил только указатель на объект, выделенный с помощью new, и я бы освободил его с другой стороны. Будьте осторожны, когда вы удаляете очередь, вы должны сначала уничтожить все ожидающие объекты! - person Salvatore Previti; 22.10.2011
comment
у меня проблема в том, что мне нужно ставить события в очередь, и они отправляются через mqueue - person ; 22.10.2011