将 openDDS 主题序列化为 `std::string`
Serialize openDDS topic to a `std::string`
我在一个项目中使用了OpenDDS。现在,为了互操作性,我们还需要将带有自定义框架的主题发送到其他机器。由于此自定义框架允许发送字符串,因此我想将主题序列化为字符串,然后再发送。
我使用的是boost::serialization,但后来我想出了一个想法,为了发送一个主题,OpenDDS 应该能够以某种方式序列化一个主题,所以我应该能够选择相应的函数并将其用于序列化数据。
检查代码,我发现了 >>=
和 <<=
运算符的重载:
void
operator<<= (
::CORBA::Any &_tao_any,
BasicType::LocalForceDataDataReader_ptr _tao_elem)
{
BasicType::LocalForceDataDataReader_ptr _tao_objptr =
BasicType::LocalForceDataDataReader::_duplicate (_tao_elem);
_tao_any <<= &_tao_objptr;
}
/// Non-copying insertion.
void
operator<<= (
::CORBA::Any &_tao_any,
BasicType::LocalForceDataDataReader_ptr *_tao_elem)
{
TAO::Any_Impl_T<BasicType::LocalForceDataDataReader>::insert (
_tao_any,
BasicType::LocalForceDataDataReader::_tao_any_destructor,
BasicType::_tc_LocalForceDataDataReader,
*_tao_elem);
}
它将主题序列化为Corba::Any
。好像可以,但是现在我需要发送Corba::Any
的内容。有没有办法把 Corba::Any
的内容放到一个字符串中,并从一个字符串中检索它的数据?或者,换句话说,我如何序列化和反序列化 Corba::Any
?
或者有更好的方法将 OpenDDS 主题序列化为字符串?
可以使用 TAO 的序列化系统来做到这一点,但最好使用 OpenDDS 正在使用的系统:https://github.com/objectcomputing/OpenDDS/blob/master/dds/DCPS/Serializer.h(或者至少我更容易写一个例子,因为我知道很多更好)
这些是一些将类型序列化到 std::string
s 和从中序列化的函数:
const OpenDDS::DCPS::Encoding encoding(OpenDDS::DCPS::Encoding::KIND_XCDR2);
template <typename IdlType>
std::string serialize_to_string(const IdlType& idl_value)
{
const size_t xcdr_size = OpenDDS::DCPS::serialized_size(encoding, idl_value);
ACE_Message_Block mb(xcdr_size);
OpenDDS::DCPS::Serializer serializer(&mb, encoding);
if (!(serializer << idl_value)) {
throw std::runtime_error("failed to serialize");
}
return std::string(mb.base(), mb.length());
}
template <typename IdlType>
IdlType deserialize_from_string(const std::string& xcdr)
{
ACE_Message_Block mb(xcdr.size());
mb.copy(xcdr.c_str(), xcdr.size());
OpenDDS::DCPS::Serializer serializer(&mb, encoding);
IdlType idl_value;
if (!(serializer >> idl_value)) {
throw std::runtime_error("failed to deserialize");
}
return idl_value;
}
在对任何二进制数据(如 CDR)使用 std::string
时也要小心,以确保它不会被解释为 null-terminated 字符串。
我在一个项目中使用了OpenDDS。现在,为了互操作性,我们还需要将带有自定义框架的主题发送到其他机器。由于此自定义框架允许发送字符串,因此我想将主题序列化为字符串,然后再发送。
我使用的是boost::serialization,但后来我想出了一个想法,为了发送一个主题,OpenDDS 应该能够以某种方式序列化一个主题,所以我应该能够选择相应的函数并将其用于序列化数据。
检查代码,我发现了 >>=
和 <<=
运算符的重载:
void
operator<<= (
::CORBA::Any &_tao_any,
BasicType::LocalForceDataDataReader_ptr _tao_elem)
{
BasicType::LocalForceDataDataReader_ptr _tao_objptr =
BasicType::LocalForceDataDataReader::_duplicate (_tao_elem);
_tao_any <<= &_tao_objptr;
}
/// Non-copying insertion.
void
operator<<= (
::CORBA::Any &_tao_any,
BasicType::LocalForceDataDataReader_ptr *_tao_elem)
{
TAO::Any_Impl_T<BasicType::LocalForceDataDataReader>::insert (
_tao_any,
BasicType::LocalForceDataDataReader::_tao_any_destructor,
BasicType::_tc_LocalForceDataDataReader,
*_tao_elem);
}
它将主题序列化为Corba::Any
。好像可以,但是现在我需要发送Corba::Any
的内容。有没有办法把 Corba::Any
的内容放到一个字符串中,并从一个字符串中检索它的数据?或者,换句话说,我如何序列化和反序列化 Corba::Any
?
或者有更好的方法将 OpenDDS 主题序列化为字符串?
可以使用 TAO 的序列化系统来做到这一点,但最好使用 OpenDDS 正在使用的系统:https://github.com/objectcomputing/OpenDDS/blob/master/dds/DCPS/Serializer.h(或者至少我更容易写一个例子,因为我知道很多更好)
这些是一些将类型序列化到 std::string
s 和从中序列化的函数:
const OpenDDS::DCPS::Encoding encoding(OpenDDS::DCPS::Encoding::KIND_XCDR2);
template <typename IdlType>
std::string serialize_to_string(const IdlType& idl_value)
{
const size_t xcdr_size = OpenDDS::DCPS::serialized_size(encoding, idl_value);
ACE_Message_Block mb(xcdr_size);
OpenDDS::DCPS::Serializer serializer(&mb, encoding);
if (!(serializer << idl_value)) {
throw std::runtime_error("failed to serialize");
}
return std::string(mb.base(), mb.length());
}
template <typename IdlType>
IdlType deserialize_from_string(const std::string& xcdr)
{
ACE_Message_Block mb(xcdr.size());
mb.copy(xcdr.c_str(), xcdr.size());
OpenDDS::DCPS::Serializer serializer(&mb, encoding);
IdlType idl_value;
if (!(serializer >> idl_value)) {
throw std::runtime_error("failed to deserialize");
}
return idl_value;
}
在对任何二进制数据(如 CDR)使用 std::string
时也要小心,以确保它不会被解释为 null-terminated 字符串。