如何使用 boost::serialization 序列化 TAO::unbouded_basic_string_sequence<T>?

How to serialize TAO::unbouded_basic_string_sequence<T> using boost::serialization?

这不起作用:

    template <class Archive, typename T>
    inline void save(Archive& arch, const TAO::unbounded_basic_string_sequence<T>& varSequence, unsigned int version)
    {
        size_t length = varSequence.length();
        arch & length & make_array(varSequence.get_buffer(), length);
    }

    template <class Archive, typename T>
    void load(Archive& arch, TAO::unbounded_basic_string_sequence<T>& varSequence, unsigned int version)
    {
        size_t length;
        arch & length;

        varSequence.length(length);
        arch & make_array(varSequence.get_buffer(), length);
    }


    template <class Archive, typename T>
    inline void serialize(Archive& arch, TAO::unbounded_basic_string_sequence<T>& varSequence, const unsigned int version)
        {
            split_free(arch, varSequence, version);
        }

编译器说:

(..)/include/boost/serialization/access.hpp:118:9: error: request for member 'serialize' in 't', which is of non-class type 'char'

我知道 boost::serialization 不支持 C 风格的字符串。理论上我可以将 std::string 用于 save(),但我不知道如何从 std::string 返回到 TAO::unbouded_basic_string_sequence - 几乎没有关于此 class 的文档。

您的困惑似乎是您希望该序列包含字符,而实际上它包含以零结尾的字符串。

从查看实现代码(确实文档不是很有帮助)来看,无界基本字符串序列似乎使用字符串特征来了解如何对字符串进行操作。

T = char 的特征表明 StringManager_T<T> class 用于 "manage" 字符串。因此,这是一个复杂的设置,其中序列存储指向 "unowned" 零终止字符串的原始指针。

但是,通过特征暗示所有操作都是通过使用 StringManager 的 string_sequence_element 代理完成的,这模拟了以 null 结尾的字符串的值语义。例如。 assignment is done like

00055 {
00056   CORBA::string_free (this->ptr_);
00057   this->ptr_ = CORBA::string_dup (p);
00058   return *this;
00059 }

我无法测试这一切的正确操作,但您可以尝试以下原始尝试:

namespace boost { namespace serialization {

    template <typename Archive, typename T>
        inline void save(Archive& ar, TAO::unbounded_basic_string_sequence<T> const& varSequence, unsigned int /*version*/)
        {
            ar & varSequence.length();

            std::basic_string<T> scratch;
            scratch.reserve(256); 

            for (size_t i = 0; i < varSequence.length(); ++i) {
                scratch.assign(varSequence[i]); // assumes zero-terminated
                ar & scratch;
            }
        }

    template <typename Archive, typename T>
        void load(Archive& ar, TAO::unbounded_basic_string_sequence<T>& varSequence, unsigned int /*version*/)
        {
            size_t length;
            ar & length;
            varSequence.length(length);

            std::basic_string<T> scratch;
            scratch.reserve(256); // some sane starting point?

            for (size_t i = 0; i < varSequence.length(); ++i) {
                ar & scratch;
                varSequence[i] = scratch.c_str();
            }
        }

    template <typename Archive, typename T>
        inline void serialize(Archive& ar, TAO::unbounded_basic_string_sequence<T>& varSequence, const unsigned int version)
        {
            split_free(ar, varSequence, version); 
        }

    template <typename Archive>
        inline void serialize(Archive& ar, SequenceOfString& sos, unsigned int /*version*/) {
            ar & base_object<TAO::unbounded_basic_string_sequence<char> >(sos);
        }

按照我的想法,你走的是一条你根本不应该走的路。当您使用 IDL 并基于它生成类型映射时,您应该使用 TAO 生成的 CORBA(反)序列化并使用 IDL 到 C++ 映射定义的类型,您现在正在使用各种内部 类。

目前您拥有 IDL 类型,您可以使用 CodecFactory 支持将它们(反)序列化为字节序列,请参阅 ACE_wrappers/TAO/tests/Codec 示例代码。使用 CodecFactory,您可以以适用于任何 CORBA 供应商的可移植方式执行此操作。