11
votes

Où mettre boost_class_export for boost :: sérialisement?

J'essaie de sérialiser un pointeur à une classe polymorphe forme . Donc, j'ai besoin d'utiliser boost_class_export Macro pour définir un GUIG pour chaque sous-classe. Le problème: Où le mettre?

Permettez-moi d'afficher un boîtier de test minimal:

formes.hpp xxx < p> export.cpp xxx

main.cpp xxx < P> sur GCC, je les compile avec xxx

ici, exportation.cpp peut sembler un peu idiot. Dans ma situation actuelle, il contient une classe de joint qui utilise l'idiome PIMPL et essaie de sérialiser sa forme (polymorphe) de la mise en œuvre . Le point important est: le boost_class_export pourrait être dans un fichier d'objet différent que le code qui appelle la sérialisation.

Voici donc le problème: où Utilisez boost_class_export ? J'ai trois options, qui peuvent être activées à l'aide de export_in_xxx macros.

  1. export_in_main fonctionne, mais n'est pas ce que je veux. Le code invoquant la sérialisation ne doit pas avoir besoin de savoir sur les détails de la mise en œuvre de la classe PIMPL.

  2. exporter_in_object compile, mais ne fonctionne pas: il se traduit par: il se traduit par un boost :: archive :: archive_exception avec le message non enregistré de vide / code>. Selon le Documentation , cela devrait Soyez résolu par des classes de base sérialisées en utilisant boost :: sérialisement :: base_object , comme je l'ai fait, mais cela n'aide pas.

  3. export_in_header ne compile même pas. Le macro boost_class_export se développe à une spécialisation de modèle (que nous aimerions être dans le fichier d'en-tête), mais aussi au définitiof d'un membre statique. Donc, j'ai une erreur de liaison sur un Définition multiple de 'boost :: archive :: détail :: init_guid :: guid_initializer' .

    Si cela importe, j'utilise g ++ 4.4.3 et boost 1.40.


2 commentaires

Avez-vous résolu ce problème? J'ai rencontré ce problème moi-même, soit obtenir une exception de classe non enregistrée au moment de l'exécution, soit boost :: archive :: détail :: init_guid :: guid_initializ er erreurs au moment de la compilation. Je suis assez soulevé, alors si vous en avez compris depuis cette question, j'apprécierais vraiment si vous partagez !! Merci!


@bguiz: pas vraiment résolu, non. Voir ma réponse ci-dessous.


6 Réponses :


1
votes

0 commentaires

4
votes

J'ai fini par mettre tout le code de sérialisation dans un en-tête s11n.h inclus dans le fichier CPP qui invoque la sérialisation. Essentiellement, le scénario export_in_main i esquisse ci-dessus, mais avec les invocations de macro boost_class_export dans un fichier différent.

Ceci ne fonctionne que tant que la seule unité de compilation comprend S11N.H , bien sûr, bien que cela fonctionne pour l'instant, ce n'est pas une solution réelle ...


2 commentaires

Hélas, cela n'a pas fonctionné pour moi - ce que j'ai fini de faire était d'utiliser archive :: register_type (static_cast (null)) dans la méthode Serialize de la classe centrale étant sévéru. Cela a fonctionné pour moi, H / w Je ne pense pas que ce soit le même scénario que vous avez rencontré ~


@Bguiz: Eh bien, ce serait un argument contre l'utilisation de l'abréviation, je suppose ...;) Mais je suis le seul à maintenir ce code, donc ce n'est pas un problème pour moi. Économise des charges de taper.



2
votes

Vous pouvez utiliser EXPORT_IN_OBJECT mais le fichier qui contient BOOST_CLASS_EXPORT doit également inclure tous les fichiers de l'archive HPP ce plan d'utilisation.

Ceci est parce que les registres macro BOOST_CLASS_EXPORT les informations de type dérivé qui archive chacun qu'il pense que vous utiliserez (implicitement déterminé sur la base desquels les archives que vous avez inclus.)

Dans votre exemple, utilisez EXPORT_IN_OBJECT mais aussi ajouter #include à export.cpp.

Dans notre code, nous avons créé archives.hpp qui contient les archives que nous utilisons et l'inclurons où que nous devons utiliser BOOST_CLASS_EXPORT. (De cette façon, nous avons une liste officielle unique des archives.)

L'inconvénient est que nous devons tout reconstruire quand nous décidons d'utiliser un nouveau type d'archives, mais nous avons constaté que beaucoup plus facile à utiliser que le support d'archives polymorphes.


0 commentaires

9
votes

Exportation classe sérialisation de les Boost.Serialization docs (1.44.0) stipule ce qui suit:


BOOST_CLASS_EXPORT code> dans le même module de source qui comprend l'un des les en-têtes de classe archive instancier Code [...] p>

Notez que le implemenation de cette Cette fonctionnalité nécessite que la BOOST_CLASS_EXPORT code> macro apparaît après et l'inclusion de toutes les archives les en-têtes de classe pour lesquels le code doit être instancié. Ainsi, le code qui utilise BOOST_CLASS_EXPORT code> ressemblera ce qui suit: p> Blockquote>

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
... // other archives

#include "a.hpp" // header declaration for class a
BOOST_CLASS_EXPORT(a)
... // other class headers and exports


2 commentaires

J'ai mis le boost_class_export_key dans mon en-tête et le boost_class_export_implement dans mon fichier de mise en œuvre. Je construis une bibliothèque de ceux-ci, puis lorsque j'essaie de sérialiser l'objet dans un exécutable qui relie la bibliothèque, le sérieliseur ne connaît pas le type. Voir cet exemple: chat.stackoverflow.com/transcript/message/28926778#28926778#28926778


@Daviddoria - Désolé, je ne peux pas vous aider là-bas. Longtemps depuis quoi faire quelque chose avec Boost.ser



0
votes

Vous pouvez utiliser et unique boost_class_export_guid () pour chaque .CPP et ajoutez-le seulement dans le fichier .cpp. pas le .h


0 commentaires

0
votes

Ce problème m'a conduit insensé jusqu'à ce que je me rendais compte que ma classe de base n'était pas polymorphe. En d'autres termes, il n'a jamais utilisé le mot-clé "virtuel" n'importe où. Parce que je n'avais pas besoin de comportement polymorphe.

Voici comment je l'ai réparé:

  1. Je viens de gifler le mot clé "virtuel" sur une méthode aléatoire dans ma classe de base.
  2. Dans mon fichier .CPP de classe dérivé, j'ai ajouté ce qui suit: XXX

    C'est tout ce que je devais faire.


0 commentaires