2012-05-21 46 views
10

注意:
Boost的存檔方案基於對稱的輸入和輸出存檔類。這是乏味寫關於他們兩人的所有的時間,所以我會用?archive爲指oarchiveiarchive
從boost :: archive :: text_oarchive_impl和boost :: archive :: text_iarchive_impl派生自定義存檔類

摘要:
我的自定義檔案的基礎類改變從binary_?archive_impltext_?archive_impl後,我的自定義存檔類不再是「發現」當編譯器實例我在其他類serialize(...)方法。

背景:
我的申請被成功讀取和寫入文件使用binary_?archive_impl的子盤(文檔和/或代碼註釋推薦這種過度從binary_?archive獲得)。我需要從二進制文件格式切換到文本格式,因此我將自定義歸檔的基類切換到text_?archive_impl。那時一切都爆炸了。

問題:
我的自定義存檔類添加功能,包括不以助推基類存在着一些額外的方法;這些方法被稱爲在我的很多類的serialize(...)方法,以及他們工作的罰款。從binary_?archive_impl改變基類text_?archive_impl後,我收到了全國各地抱怨說我的自定義方法text_?archive不存在的地方編譯錯誤。那麼,很明顯(!!!),但他們確實存在在我的定製檔案,他們工作就好了當我使用Boost的二進制基類。這是怎麼回事?

我發現了什麼,而我暫時的 - 但不良 - 解決方案:
撕裂我的頭髮和兜兜轉轉了大約一天後,這是我發現了什麼......

1)前一段時間(升壓1.34我相信),文件「binary_?archive.hpp」被分成「binary_?archive_impl.hpp」和「binary_?archive.hpp」(後者的#include前者)。這個不是完成「text_?archive.hpp」。 (因此,我將應用程序的#include行從「binary_?archive_impl.hpp」更改爲「text_?archive.hpp」。)

2)如果我將「text_?archive.hpp」分成兩部分部分和#只包含「..._ impl.hpp」頭文件,一切正常。 (但我真的不要想要修改我的Boost安裝!)

3)仔細查看這些頭文件並繞了一下,我發現如果我使用原始的,未修改的頭文件並註釋掉行

BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_oarchive) 

(和text_iarchive同樣),然後一切工作再次正常。 (順便說一下,我在我自己的存檔代碼中有類似的行來「註冊」我的自定義存檔。)

神祕,和我的困境:
A)爲什麼這些線的存在弄髒了的作品? ...爲什麼刪除它們會使事情發揮作用? ......我可以通過這樣做破壞什麼(不知道它)?

B)很久以前,爲什麼「text_?archive.hpp」文件而不是與「binary_?archive.hpp」文件分開? (庫是否損壞?是否應該修復?)

C)有沒有什麼方法可以在我的應用程序代碼中解決這個問題,而無需修改我的Boost安裝?

P.S.我正在使用Boost 1.48和Visual Studio 2010(64位)
P.P.S.我想所有的上述同樣適用於text_w?archive

回答

1

盡我可以告訴它的升壓連載中的錯誤。我們將看到here.

A)
1.添加BOOST_SERIALIZATION_REGISTER_ARCHIVE與您新的存檔不起作用,因爲默認的文本檔案已經註冊的 - 只有在註冊似乎被允許的。
2.刪除它們使其工作,因爲只有您的自定義類被註冊。 3 3。通過刪除它們,你已經打破了使用默認文本存檔的能力 - 你的類將被註冊。


我相當肯定的是,「text_?archive.hpp」文件應該已經分手了像「binary_?archive.hpp」文件。補丁提升任何人?

Ç
最好的解決方案是提交補丁,以提高其將這些文件了。對於臨時解決方案而言,最好的方法是將補丁文件本地放入項目中,直到補丁程序進入提升狀態。

1

我想這是一個評論,因爲它是一個暗示,而不是答案。不過,我沒有看到爲您的問題添加評論的選項(並且我不認爲編輯按鈕會按照我的意願進行操作)。

在我的1.49.0安裝中,我也看到了文本類型的相應實現文件。它們位於impl目錄中的.ipp格式。時間標記表明它們最近沒有變化,所以應該與1.48相同。它可能會幫助你解決問題。

根據Dave Abrahams,.ipp files are supposed to hide the implementation。不知道他們爲什麼選擇不同的風格。

---------- + 1個計算器無2936 2009年12月5日./binary_iarchive_impl.hpp

---------- + 1計算器無2966 2009年12月5日。 /binary_oarchive_impl.hpp

---------- + 1計算器無1392 2007年11月25日./detail/basic_archive_impl.hpp

---------- + 1 stackoverflow無3458 2009年5月20日./impl/text_iarchive_impl.ipp

---------- + 1計算器無3290 2005年7月2日./impl/text_oarchive_impl.ipp

---------- + 1計算器無3020 2008年6月26日。 /impl/text_wiarchive_impl.ipp

---------- + 1計算器無2244 2005年7月2日./impl/text_woarchive_impl.ipp

+0

我也注意到這些文件(在我的1.48安裝),但它們不是解決辦法。作爲一個臨時的解決方案,我已經完成了將'text_?archive'頭文件分割成單獨文件的工作,並且這些'.ipp'文件也需要修改。所以我有一個臨時解決方案,但是我仍然不知道這是否應該作爲庫中的錯誤報告,或者如果這些文件是正確的,我應該在代碼中做不同的事情。 – aldo

0

我有同樣的問題綁定爲我的庫實現自定義存檔。 我發現了一個可能的解決方法,它似乎效果很好,所以我會與你分享:

無法在boost存檔中導出帶有修改的序列化語法的類,所以我們必須避免它在所有。

提升檔案登記使用正確的重載函數,使指針序列化類型實例(如boost/archive/detail/register_archive.hpp

# define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive)     \ 
namespace boost { namespace archive { namespace detail {    \ 
                     \ 
template <class Serializable>           \ 
BOOST_DEDUCED_TYPENAME _ptr_serialization_support<Archive, Serializable>::type \ 
instantiate_ptr_serialization(Serializable*, Archive*, adl_tag);    \ 
                     \ 
}}} 

注意adl_tag補充說,可被用來製造提升能看看裏面一個很酷的過載功能我們的實施。簡單地說一個新的註冊聲明是這樣的:

// ARCHIVES REGISTRATION // 

namespace MyLib { 
struct adl_tag {}; 
} 

namespace boost { namespace archive { namespace detail { 
template <class Serializable> 
void instantiate_ptr_serialization(Serializable*, int, MyLib::adl_tag) {} 
} } } 

# define MYLIB_SERIALIZATION_REGISTER_ARCHIVE(_Archive)     \ 
namespace boost { namespace archive { namespace detail {    \ 
template <class Serializable>           \ 
BOOST_DEDUCED_TYPENAME _ptr_serialization_support<_Archive, Serializable>::type \ 
instantiate_ptr_serialization(Serializable*, _Archive*, MyLib::adl_tag); }}} 

現在你必須使自己的導出宏如(/boost/serialization/export.hpp):

namespace MyLib { 
namespace extra_detail { 

template<class T> 
struct guid_initializer 
{ 
    void export_guid(mpl::false_) const { 
     // generates the statically-initialized objects whose constructors 
     // register the information allowing serialization of T objects 
     // through pointers to their base classes. 
     boost::archive::detail:: 
       instantiate_ptr_serialization((T*)0, 0, 
               MyLib::adl_tag()); 
    } 
    void export_guid(mpl::true_) const { 
    } 
    guid_initializer const & export_guid() const { 
     BOOST_STATIC_WARNING(boost::is_polymorphic<T>::value); 
     // note: exporting an abstract base class will have no effect 
     // and cannot be used to instantitiate serialization code 
     // (one might be using this in a DLL to instantiate code) 
     //BOOST_STATIC_WARNING(! boost::serialization::is_abstract<T>::value); 
     export_guid(boost::serialization::is_abstract<T>()); 
     return *this; 
    } 
}; 

template<typename T> 
struct init_guid; 

} // extra_detail 
} // namespace MyLib 



#define MYLIB_CLASS_EXPORT_IMPLEMENT(T)      \ 
    namespace MyLib {          \ 
    namespace extra_detail {         \ 
    template<>            \ 
    struct init_guid<T> {         \ 
     static guid_initializer<T> const & g;    \ 
    };              \ 
    guid_initializer<T> const & init_guid<T>::g =  \ 
     ::boost::serialization::singleton<     \ 
      guid_initializer<T>       \ 
     >::get_mutable_instance().export_guid();    \ 
    }}              \ 
/**/ 

確定它的所有,現在你可以定義自定義歸檔和與註冊它:

MYLIB_SERIALIZATION_REGISTER_ARCHIVE(MyLib::xml_iarchive) 

,隨時隨地你定義爲你的類序列化,通過MyLib中具有特殊的語法只可讀:: custom_archive你可以使用你博覽會RT執行

BOOST_CLASS_EXPORT_KEY(MyClass) // in header 
MYLIB_CLASS_EXPORT_IMPLEMENT(MyClass) // in cpp 

(請注意,關鍵的出口保持不變提振...)

這是真的很酷,因爲可以讓您的自定義歸檔和檔案提高生活在一起沒有錯誤..每當你想要一個boost序列化只需使用BOOST_CLASS_EXPORT,並且只要使用MYLIB_CLASS_EXPORT將您的類序列化即可。

希望這可能會有用!

安德烈裏戈尼Garola

相關問題