I've been pulling my hair out for a couple of days trying to get this to work.

When I serialize something from a base pointer, it throws an "unregistered_class" exception.

I know the type of object that's being serialized and that class has "BOOST_CLASS_EXPORT_KEY" in the header and "BOOST_CLASS_EXPORT_IMPLEMENT" in the cpp file with the same name.

In the save and load functions I also have:
boost::serialization::void_cast_register(
    static_cast<Derived*>(NULL),
    static_cast<Base*>(NULL));

The base class is an abstract base class with one pure virtual function method. But here are the differences:
1) I tried using the "ASSUME_ABSTRACT....." macro. That didn't do anything for me.
2) The abstract base class also has a cpp file with some code in it. I'm not sure if that matters or not...

Here's the thing. I can get the derived class's "save" method to be called with this code:

std::ofstream o(case_path_ + "/" + file_name);
if (o.good())
{

    // MUST HAVE THIS
    boost::serialization::void_cast_register<Derived, Base>(
        static_cast<Derived*>(NULL),
        static_cast<Base*>(NULL));

    boost::archive::polymorphic_text_oarchive oa(o);
    boost::archive::polymorphic_oarchive & oa_interface = oa;
    oa_interface << base_ptr;
}

Having the void_cast_register() there sort of defeats the purpose though. I shouldn't need to pre-register them.
In all the examples, I see the void_cast_register() inside of the "save" and "load" methods, which is what I have already.
All my serialization code resides in cpp files.
Also, the serialization code resides in a static lib.
But the archive creation and the action to serialize is performed in a dynamic lib.
I am also using polymorphic archives everywhere.
I've also forced template instantiation of all serialization code and polymorphic archive interface stuff.

Any clue?