Search code examples
c++boostboost-serialization

boost serialization of opaque types


I want to be able to serialize a Windows HANDLE:

typedef void *HANDLE

If I try to compile using following:

struct Foo
{
    HANDLE file;

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

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

I get compile errors:

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
        ]

But if I change file to an int, everything is fine. How do I tell boost to serialize HANDLEs as ints?

Thanks


Solution

  • Ended up solving the problem by splitting the serialization. Seems like a hack though:

    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()
    };