2012-02-08 13 views
6

Sto cercando un esempio (funzionante) per serializzare esternamente una struttura di classe in una DLL. Al momento non riesco a trovare alcun esempio per questo. La documentazione di Boost sta solo indicando alcune macro, i forum e i newsgroup stanno semplicemente discutendo problemi specifici con le loro soluzioni.Inserire la serializzazione di una classe in una DLL

Quindi sto chiedendo un esempio per serializzare (esternamente) una struttura di classe come la seguente. Insieme al codice di classe ho aggiunto un mio codice per la serializzazione (che non funziona, vedi in basso per il messaggio di errore).

class Foo 
{ 
public: 
    Foo() { number_ = 0; } 
    virtual ~Foo() {} 

    int getNumber() { return number_; } 
    void setNumber(int var) { number_ = var; } 
private: 
    int number_; 
}; 

class Bar : public Foo 
{ 
public: 
    Bar() { doubleNumber_ = 0.0; } 
    virtual ~Bar() {} 

    double getDouble() { return doubleNumber_; } 
    void setDouble(double var) { doubleNumber_ = var; } 

private: 
    double doubleNumber_; 
}; 

Tutto quello che ho finora è il codice come questo:

serializeFoo.h

#ifndef _SERIALIZE_FOO_H_ 
#define _SERIALIZE_FOO_H_ 

#include "Foo.h" 
#include <boost/serialization/split_free.hpp> 
#include <boost/serialization/version.hpp> 

namespace boost { 
namespace serialization { 

template <typename Archive> 
void save(Archive& ar, const Foo& object, const unsigned int version) 
{ 
    ar << object.getNumber(); 
} 

template <typename Archive> 
void load(Archive& ar, Foo& object, const unsigned int version) 
{ 
    int number; 
    ar >> number; 
    object.setNumber(number); 
} 

}} //namespace brackets 

BOOST_SERIALIZATION_SPLIT_FREE(Foo) 

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/serialization/export.hpp> 
BOOST_CLASS_EXPORT_KEY(Foo) 

#endif //_SERIALIZE_FOO_H_ 

serializeFoo.cpp

#include "serializeFoo.h" 
BOOST_CLASS_EXPORT_IMPLEMENT(Foo) 

seriali zeBar.h:

#ifndef _SERIALIZE_BAR_H_ 
#define _SERIALIZE_BAR_H_ 

#include "Bar.h" 
#include <boost/serialization/split_free.hpp> 
#include <boost/serialization/version.hpp> 

namespace boost { 
namespace serialization { 

template <typename Archive> 
void save(Archive& ar, const Bar& object, const unsigned int version) 
{ 
    ar << base_object<Foo>(object); 
    ar << object.getDouble(); 
} 

template <typename Archive> 
void load(Archive& ar, Bar& object, const unsigned int version) 
{ 
    double doubleNumber; 
    ar >> doubleNumber; 
    object.setDouble(doubleNumber); 
} 

}} //namespace brackets 

BOOST_SERIALIZATION_SPLIT_FREE(Bar) 

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/serialization/export.hpp> 
BOOST_CLASS_EXPORT_KEY(Bar) 

#endif //_SERIALIZE_BAR_H_ 

serializeBar.cpp:

#include "serializeBar.h" 
BOOST_CLASS_EXPORT_IMPLEMENT(Bar) 

La serializzazione codice va in una DLL e dovrebbe essere utilizzato in un altro progetto utilizzando le classi Foo e Bar. Tutto si compila bene, ma in fase di esecuzione ricevo il messaggio
unregistered class - derived class not registered or exported

Così ho usato i macro sbagliati? Mi manca una macro? Il codice sopra è corretto o c'è qualche tipo di errore strutturale? Forse questo potrebbe essere utile anche per molte altre persone, non penso che mettere la serializzazione di una classe in una DLL sia molto esotico ...

+0

Su cosa ho visto su Boost-docs era 'BOOST_SERIALIZATION_FACTORY_0 (Foo)', ma non so se è necessario e se dovrei usarlo. Link: http://www.boost.org/doc/libs/1_37_0/libs/serialization/doc/special.html#dlls – MOnsDaR

+0

Beh, se ti fa sentire meglio, ho un progetto in cui funziona bene e il codice sembra piuttosto identico a quello che hai, tranne per il fatto che includo le intestazioni di archivio nella parte superiore del file di intestazione. Post scriptum è tecnicamente un '.so', non un' .dll', non dovrebbe fare la differenza però ... – TC1

+0

Hai ragione, volevo scrivere "Shared lib" all'inizio, ma ho scritto DLL perché volevo mostrare che attualmente è un problema con questo specifico tipo di lib condivisa. – MOnsDaR

risposta

1

mi sono imbattuto in un problema simile di recente, 3 anni dopo questa domanda è stato chiesto. Alla fine ho scoperto una soluzione alternativa per risolverlo. Nell'esempio sopra.

  • Bar è una sottoclasse di Foo, quindi devono essere registrati/esportazione;
  • serializeFoo.cpp istanzia una classe modello GUID da registrare/esportare Foo;
  • serializeBar.cpp istanzia una classe modello GUID per registrarsi/esportare Bar;
  • Le regole per includere tutti i tipi di archivio necessari prima dell'esportazione delle chiavi di classe sono rispettate;
  • Entrambe le unità di traduzione sono collegate insieme per creare una DLL.

Presumo nel vostro exe, mentre si sta cercando di puntate un puntatore Foo* che punta a un oggetto Bar, avete ottenuto l'errore "non registrato classe blahblah". Questo perché Boost.Serialization in qualche modo non genera correttamente un GUID per la classe Barprima del viene chiamata la funzione serialize.

Non so perché questo accada, ma sembra che il GUID sia generato in modo pigro - se non viene utilizzato nessuno dei simboli dall'unità di traduzione serializeBar.cpp, nessuno del codice di istanziazione/inizializzazione definito in quella traduzione verrà eseguita un'unità - che include la registrazione/esportazione della classe di Bar.

Per dimostrare che, si può provare a utilizzare un simbolo (fittizio) in serializeBar.cpp (ad esempio chiamando una funzione fittizia implementato in serializeBar.cpp) prima di chiamare qualsiasi funzione di serializzazione per Foo*. Il problema dovrebbe scomparire.

Spero che aiuti.

+0

3 anni ... dannazione! : D – MOnsDaR

0

Difficile dirlo ... Ci sono molte possibilità per le cose sbagliare. Consiglio di scaricare il codice di prova per la serializzazione boost (www.boost.org/doc/libs/1_48_0/libs/serialization/test/). Dai un'occhiata ai test case su Ah, A.cpp e dll_a.cpp (che fondamentalmente testano il tuo scenario) e prova a farlo funzionare al di fuori del sistema boost test: usa il tuo ambiente di costruzione, prova a modificare le opzioni del compilatore/linker corrisponde a quelli di boost test suite per il set di strumenti.

Onestamente, secondo me, in alcuni punti, Boost serializzazione attraversa il confine di ciò che è affidabile possibile con puro C++ costruire modello w/o strumenti esterni ...

1

la suite di test e demo distribuito con la biblioteca serializzazione dimostrano esattamente questa struttura Quindi prima assicurati che funzioni. Quindi confronta il tuo esempio con esso.

Robert Ramey

"Onestamente, IMHO, in alcuni punti, Boost serializzazione attraversa il confine di ciò che è affidabile possibile con puro C++ costruire modello w/o strumenti esterni ..."

hmmmmmm - così attraversa il confine come ciò che è possibile? Comunque sei abbastanza corretto nello spirito. Sono stati compiuti notevoli sforzi per implementare tutto ciò che è stato ritenuto necessario affinché un pacchetto di questo tipo fosse accettabile.

RR

0

Usa BOOST_CLASS_EXPORT per registrare tutte le classi che si desidera serializzare

Problemi correlati