将 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::strings 和从中序列化的函数:

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 字符串。