2013-11-23 24 views
0

我似乎無法獲得boost :: serialization的正常工作。在包含類和歸檔頭文件後,我使用BOOST_CLASS_EXPORT_GUID宏將類.cpp文件分散了,但我仍然遇到unregistered_class異常。Boost序列化未註冊的類錯誤

我環顧四周,似乎無論我能找到的是1.過時,處理舊版本的庫,或2.僅適用於一個簡單的單文件解決方案,其中所有可序列化的類都已定義一個接一個地。沒有我找到的幫助。

我目前的解決方案由一個項目組成,它被編譯成一個靜態庫,其中包含基本可歸檔類的核心功能,另一個測試項目最終將充實到更具體的邏輯層。讓所有的工作與boost :: serialization一起工作證明是一場噩夢。我幾乎想要自己寫。

不管怎樣,在問題這引起了異常的類的標題,它看起來像這樣的定義:

#include <boost/serialization/assume_abstract.hpp> 
#include <boost/serialization/serialization.hpp> 
// Other includes... 

namespace GameCore { class Component; } 
// Forward declare some boost::serialization functions that appear at the bottom. 
// ... 
BOOST_SERIALIZATION_ASSUME_ABSTRACT(GameCore::Component); 

namespace GameCore 
{ 
    // Some forward declares.. 

////////////////////////////////////////////////////////////////////////// 
// Base component type. 
////////////////////////////////////////////////////////////////////////// 
class Component : public Updatable, public Object 
{ 
    friend class boost::serialization::access; 

protected:         
    template <typename Archive>     
    friend void boost::serialization::serialize(Archive& archive, Component& object, const unsigned int version); 
    template <typename Archive> friend void boost::serialization::load_construct_data(Archive& archive, Component* t, const unsigned int version); 
    template <typename Archive> friend void boost::serialization::save_construct_data(Archive& archive, const Component* t, const unsigned int version);  

public: 
    Component(GameObject& owner); 
    virtual ~Component() = 0; 

    // Irrelevant stuff.. 

    GameObject& gameObject; 
    Transform* transform; 
}; 
} 
// The component includes have to be placed here because it would otherwise create a cyclic inclusion when trying to compile the 
// individual component classes, say, Transform, which would end up including itself. 
#include "Transform.h" 


namespace boost 
{ 
    namespace serialization 
    { 
     template<class Archive> 
     inline void save_construct_data(Archive& archive, const GameCore::Component* t, const unsigned int version) 
     { 
      archive << t->gameObject; 
     } 


    template<class Archive> 
    inline void load_construct_data(Archive& archive, GameCore::Component* t, const unsigned int version) 
    { 
     // Retrieve data from archive required to construct new instance. 
     GameCore::GameObject owner; 
     archive >> owner; 

     // Invoke inplace constructor to initialize instance of class. 
     ::new(t)GameCore::Component(owner); 
    } 


    ////////////////////////////////////////////////////////////////////////// 
    // Serialization function for save/load. 
    ////////////////////////////////////////////////////////////////////////// 
    template <typename Archive> 
    void serialize(Archive& archive, GameCore::Component& t, const unsigned int version) 
    { 
     archive & boost::serialization::base_object<GameCore::Object>(t); 
     archive & boost::serialization::base_object<GameCore::Updatable>(t); 
     archive & t.gameObject; 
     archive & t.transform; 
    } 
} 
} 

也就是說一個頭文件。對不起,冗長。它的.cpp文件開頭是這樣的:當我嘗試派生Component,這本身是一個抽象類存檔一個實例對象

#include "Component.h" 

#include <boost/serialization/export.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/archive/text_oarchive.hpp> 
// Other includes... 

BOOST_CLASS_EXPORT_GUID(GameCore::Component, "GameCore::Component"); 

// Class method definitions here. 

的異常。我歸檔通過不同的管理類中定義一個簡單的方法:

std::ofstream outputFile(fileName); 
boost::archive::text_oarchive outputArchive(outputFile); 
outputArchive << objects; 

其中objectsObjectstd::listObject是所有事物(包括Component)從中派生的基類。

我道歉,如果這聽起來很繞口,但只有三層繼承的,我相信我有系列化躡手躡腳的想法之前,整潔和有效的架構英寸

如果你能幫助我擺脫非理性的例外我會爲你的靈魂點燃一支蠟燭!

更新:有趣的是,所有派生類Component都沒有引發異常。

回答

5

油炸我的神經元尋找一個答案之後,我在這條線的文檔中偶然發現:

靜態庫和序列化

代碼數據類型的序列化可以在圖書館保存,就像 它可以用於其他類型的實現。這效果很好,並且 可以節省大量的編譯時間。僅在庫中編譯序列化 定義。針對您打算在庫中使用的所有歸檔類,明確實例化序列化代碼 。對於導出的 類型,只能在標頭中使用BOOST_CLASS_EXPORT_KEY。對於導出的類型, 僅在 庫中編譯的定義中使用BOOST_CLASS_EXPORT_IMPLEMENT。對於任何特定的類型,應該只有一個文件,其中包含該類型的BOOST_CLASS_EXPORT_IMPLEMENT 。這確保了程序中只有一個序列化代碼副本存在於 中。它可以避免浪費的空間以及在同一個程序中使用不同版本的 序列化代碼的可能性。在多個文件中包含 BOOST_CLASS_EXPORT_IMPLEMENT可能會導致 由於重複的符號或投擲運行時異常而導致鏈接失敗。

拆分BOOST_CLASS_EXPORTBOOST_CLASS_EXPORT_KEYBOOST_CLASS_EXPORT_IMPLEMENT似乎工作。