Sign in to follow this  
Happy Noodle Boy

[solved] linker errors and boost serialization

Recommended Posts

Can somebody please toss me a clue regarding virtual member functions and boost::serialization? Is there something in particular I need to do to let boost know that a class has a vtbl? I get a linker failure with three errors:
unresolved: boost::archive::detail::archive_pointer_oserializer<Archive>::find(...) referenced in: boost::archive::detail::save_pointer_type<Archive, T *>::polymorphic<T>::save(...)
unresolved: boost::serialization::void_downcast(...) referenced in: boost::archive::detail::save_pointer_type<Archive, T *>::polymorphic<T>::save(...)
unresolved: boost::serialization::detail::extended_type_info_typeid_0::get_derived_extended_type_info(...) referenced in: boost::serialization::detail::extended_type_info_typeid_1<T const >::get_derived_extended_type_info(...)
//  linker errors using boost serialization on polymorphic class

#include <boost/archive/xml_woarchive.hpp>
#include <boost/serialization/nvp.hpp>


using boost::archive::xml_woarchive;
using std::wofstream;


class Foo
{
public:
    virtual ~Foo() {};	//  It's the 'virtual' keyword that seems to cause the linker errors.

private:
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive &archive, const unsigned int version);

    int m_i;
};


template<class Archive>
void Foo::serialize(Archive &archive, const unsigned int /* version */)
{
    archive & BOOST_SERIALIZATION_NVP(m_i);
}


template <class Archive>
void failToLink(Archive &archive)
{
    wofstream stream(L"Foo.xml");

    xml_woarchive archive(stream);

    Foo foo;
    Foo *pFoo = new Foo;

//  archive << BOOST_SERIALIZATION_NVP(foo);	//  ok
    archive << BOOST_SERIALIZATION_NVP(pFoo);	//  linker fails
}



Foo.obj : error LNK2019: unresolved external symbol "public: static class boost::archive::detail::basic_pointer_oserializer const * __fastcall boost::archive::detail::archive_pointer_oserializer<class boost::archive::xml_woarchive>::find(class boost::serialization::extended_type_info const &)" (?find@?$archive_pointer_oserializer@Vxml_woarchive@archive@boost@@@detail@archive@boost@@SIPBVbasic_pointer_oserializer@234@ABVextended_type_info@serialization@4@@Z) referenced in function "public: static void __fastcall boost::archive::detail::save_pointer_type<class boost::archive::xml_woarchive,class Foo *>::polymorphic<class Foo>::save(class boost::archive::xml_woarchive &,class Foo const &,class boost::archive::detail::basic_pointer_oserializer const *)" (?save@?$polymorphic@VFoo@@@?$save_pointer_type@Vxml_woarchive@archive@boost@@PAVFoo@@@detail@archive@boost@@SIXAAVxml_woarchive@45@ABVFoo@@PBVbasic_pointer_oserializer@345@@Z)
Foo.obj : error LNK2019: unresolved external symbol "void const * __fastcall boost::serialization::void_downcast(class boost::serialization::extended_type_info const &,class boost::serialization::extended_type_info const &,void const * const,bool)" (?void_downcast@serialization@boost@@YIPBXABVextended_type_info@12@0QBX_N@Z) referenced in function "public: static void __fastcall boost::archive::detail::save_pointer_type<class boost::archive::xml_woarchive,class Foo *>::polymorphic<class Foo>::save(class boost::archive::xml_woarchive &,class Foo const &,class boost::archive::detail::basic_pointer_oserializer const *)" (?save@?$polymorphic@VFoo@@@?$save_pointer_type@Vxml_woarchive@archive@boost@@PAVFoo@@@detail@archive@boost@@SIXAAVxml_woarchive@45@ABVFoo@@PBVbasic_pointer_oserializer@345@@Z)
Foo.obj : error LNK2019: unresolved external symbol "protected: static class boost::serialization::extended_type_info const * __fastcall boost::serialization::detail::extended_type_info_typeid_0::get_derived_extended_type_info(class type_info const &)" (?get_derived_extended_type_info@extended_type_info_typeid_0@detail@serialization@boost@@KIPBVextended_type_info@34@ABVtype_info@@@Z) referenced in function "public: static class boost::serialization::extended_type_info const * __fastcall boost::serialization::detail::extended_type_info_typeid_1<class Foo const >::get_derived_extended_type_info(class Foo const &)" (?get_derived_extended_type_info@?$extended_type_info_typeid_1@$$CBVFoo@@@detail@serialization@boost@@SIPBVextended_type_info@34@ABVFoo@@@Z)
Any ideas would be much appreciated.
[Edit: fixed error summary for 2nd linker error.] [Edit: problem solved; pre-built libraries used different calling convention.] [Edited by - Happy Noodle Boy on October 16, 2007 2:39:42 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Did you build the boost libraries with bjam?


I used the pre-built libraries from Boost Consulting, and they've linked and worked correctly for simple non-polymorphic classes.

Share this post


Link to post
Share on other sites
Is this relevant?

Quote:
Abstract
When serializing an object through a pointer to its base class and that base class is abstract (i.e. has at least one virtual function assigned a value of 0), A compile error will be emitted. This is addressable in one over several ways:

* remove the =0 in the base classes so that the base class is no longer abstract.
* implement is_abstract for your compiler. (code written according to the C++ standard is included with this library. But it is known to fail on several compilers.
* use the macro BOOST_IS_ABSTRACT(my_class) to indicate that the class is an abstract base class. This will cause the compiler to avoid generating code that causes this error.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
Is this relevant?


No pure virtuals in the class, so I don't think it is relevant. Just to be sure, I made the destructor pure virtual, and then used the BOOST_IS_ABSTRACT macro, but it didn't help any. Thanks for the idea, though.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Did you build the boost libraries with bjam?

No, but apparently I should have. My projects were configured for __fastcall calling convention, and the binaries from Boost Consulting use __cdecl. Thanks for the hint.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this