提升不透明类型的序列化

时间:2012-09-09 21:02:26

标签: c++ boost boost-serialization

我希望能够序列化Windows HANDLE:

typedef void *HANDLE

如果我尝试使用以下代码进行编译:

struct Foo
{
    HANDLE file;

protected:
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int /*version*/)
    {
        ar & file;
    }
};

我收到编译错误:

c:\projects\3rdparty\src\boost\include\boost/mpl/print.hpp(51) : warning C4308: negative integral constant converted to unsigned type
        c:\projects\3rdparty\src\boost\include\boost/serialization/static_warning.hpp(92) : see reference to class template instantiation 'boost::mpl::print<T>' being compiled
        with
        [
            T=boost::serialization::BOOST_SERIALIZATION_STATIC_WARNING_LINE<98>
        ]
        c:\projects\3rdparty\src\boost\include\boost/archive/detail/check.hpp(98) : see reference to class template instantiation 'boost::serialization::static_warning_test<B,L>' being compiled
        with
        [
            B=false,
            L=98
        ]
        c:\projects\3rdparty\src\boost\include\boost/archive/detail/oserializer.hpp(313) : see reference to
function template instantiation 'void boost::archive::detail::check_object_tracking<T>(void)' being compiled
        with
        [
            T=Foo
        ]
        c:\projects\3rdparty\src\boost\include\boost/archive/detail/oserializer.hpp(525) : see reference to
function template instantiation 'void boost::archive::detail::save_non_pointer_type<Archive>::invoke<T>(Archive &,T &)' being compiled
        with
        [
            Archive=boost::archive::text_oarchive,
            T=Foo
        ]

但如果我将file更改为int,一切都会好的。 如何告诉boost将HANDLEs序列化为整数?

由于

2 个答案:

答案 0 :(得分:4)

HANDLEwinnt.h中定义的特定于Windows API的数据类型。根据{{​​3}},

  

对象的句柄。   此类型在WinNT.h中声明如下:

typedef PVOID HANDLE;

所以,现在我们看到HANDLE实际上只是void * - 表示对象的句柄。想想你正在尝试做什么;将指针序列化到Windows API中的某个对象是否有意义?

相反,尝试序列化检索等效HANDLE所需的内容;根据会员的名字来判断,我猜你会用MSDN - 所以,你需要知道......

  • 文件名
  • 所需的访问权限(例如GENERIC_READ | GENERIC_WRITE
  • 共享模式(例如FILE_SHARE_DELETE
  • (可选)安全属性
  • 创作处置(即CREATE_NEWTRUNCATE_EXISTING等)
  • 文件或设备标志和属性
  • (可选)模板文件 - 用于在创建文件时复制其属性

现在,如果你真的不希望这样做 - 你是肯定你想要指针值 - 也许尝试在投射后序列化它CreateFilestd::intptr_tstd::uintptr_t(从<{1}}开始,可能在C ++ 11中定义)。

cstdint

...那么你应该把它与以下内容结合起来(当反序列化时):

ar & reinterpret_cast<std::intptr_t>(file);

答案 1 :(得分:0)

通过拆分序列化来解决问题。看起来像黑客:

struct Foo
{
    HANDLE file;

protected:
    friend class boost::serialization::access;

    template<class Archive>
    void save(Archive & ar, const unsigned int /*version*/) const
    {
        unsigned int _file = reinterpret_cast<unsigned int>(file);
        ar & _file;
    }

    template<class Archive>
    void load(Archive & ar, const unsigned int /*version*/)
    {
        unsigned int _file;
        ar & _file;
        file = reinterpret_cast<HANDLE>(_file);
    }
    BOOST_SERIALIZATION_SPLIT_MEMBER()
};