1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2// test_dll_plugin.cpp
3
4// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
5// Use, modification and distribution is subject to the Boost Software
6// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8
9// should pass compilation and execution
10
11// Note this test creates, serializes, and destroys
12// a class instance while knowing nothing more than its
13// exported class ID (GUID) and a base class from which
14// it is derived. This is referred to as a "plugin"
15// since the same program could, without recompilation,
16// manipulate any number of derived types - even those
17// which have not been yet been created.
18
19#include <fstream>
20
21#include <cstdio> // remove
22#include <boost/config.hpp>
23#if defined(BOOST_NO_STDC_NAMESPACE)
24namespace std{
25 using ::remove;
26}
27#endif
28
29#include <boost/archive/archive_exception.hpp>
30
31// for now, only test with simple text and polymorphic archive
32#include "test_tools.hpp"
33
34#include <boost/serialization/base_object.hpp>
35#include <boost/serialization/export.hpp>
36#include <boost/serialization/type_info_implementation.hpp>
37#include <boost/serialization/access.hpp>
38#include <boost/serialization/void_cast.hpp>
39#include <boost/serialization/extended_type_info.hpp>
40
41#include "polymorphic_base.hpp"
42
43// declare and implement a derived class in our own executable
44class polymorphic_derived1 : public polymorphic_base
45{
46 friend class boost::serialization::access;
47 template<class Archive>
48 void serialize(Archive &ar, const unsigned int /* file_version */){
49 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(polymorphic_base);
50 }
51 const char * get_key() const{
52 return
53 boost::serialization::type_info_implementation<
54 polymorphic_derived1
55 >::type::get_const_instance().get_key();
56 }
57public:
58 virtual ~polymorphic_derived1(){}
59};
60
61// This class is derived from polymorphic_base which uses the no_rtti system
62// rather than the typeid system. This system uses the exported name as the
63// type identifier key. This MUST be exported!!!
64BOOST_CLASS_EXPORT(polymorphic_derived1)
65
66// MWerks users can do this to make their code work
67BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(polymorphic_base, polymorphic_derived1)
68
69// save exported polymorphic class
70void save_exported(const char *testfile)
71{
72 test_ostream os(testfile, TEST_STREAM_FLAGS);
73 test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
74
75 polymorphic_base *rb1 = new polymorphic_derived1;
76
77 // get the eti record for the exported type "polymorphic_derived2"
78 boost::serialization::extended_type_info const * const d2_eti =
79 boost::serialization::extended_type_info::find(
80 key: "polymorphic_derived2"
81 );
82 assert(NULL != d2_eti);
83
84 // create a new instance of the type referred to by this record.
85 // in this example, we happen to know that the class constructor
86 // takes no arguments.
87 void const * const rd2 = d2_eti->construct();
88 assert(NULL != rd2);
89
90 // transform the pointer to a pointer to the base class
91 polymorphic_base const * const rb2
92 = static_cast<polymorphic_base const *>(
93 boost::serialization::void_upcast(
94 derived: * d2_eti,
95 base: boost::serialization::type_info_implementation<polymorphic_base>
96 ::type::get_const_instance(),
97 t: rd2
98 )
99 );
100
101 // export will permit correct serialization
102 // through a pointer to a base class
103 oa << BOOST_SERIALIZATION_NVP(rb1);
104 oa << BOOST_SERIALIZATION_NVP(rb2);
105
106 // don't need these any more - don't leak memory
107 delete rb1;
108 // note delete original handle - not runtime cast one !!!
109 //delete rb2;
110 d2_eti->destroy(rd2);
111}
112
113// save exported polymorphic class
114void load_exported(const char *testfile)
115{
116 test_istream is(testfile, TEST_STREAM_FLAGS);
117 test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
118
119 polymorphic_base *rb1 = NULL;
120 polymorphic_base *rb2 = NULL;
121
122 // export will permit correct serialization
123 // through a pointer to a base class
124 ia >> BOOST_SERIALIZATION_NVP(rb1);
125
126 BOOST_CHECK_MESSAGE(
127 boost::serialization::type_info_implementation<polymorphic_derived1>
128 ::type::get_const_instance()
129 ==
130 * boost::serialization::type_info_implementation<polymorphic_base>
131 ::type::get_const_instance().get_derived_extended_type_info(*rb1),
132 "restored pointer b1 not of correct type"
133 );
134 ia >> BOOST_SERIALIZATION_NVP(rb2);
135
136 // get the eti record for the exported type "polymorphic_derived2"
137 boost::serialization::extended_type_info const * const d2_eti =
138 boost::serialization::extended_type_info::find(
139 key: "polymorphic_derived2"
140 );
141 assert(NULL != d2_eti);
142
143 BOOST_CHECK_MESSAGE(
144 * d2_eti
145 ==
146 * boost::serialization::type_info_implementation<polymorphic_base>
147 ::type::get_const_instance().get_derived_extended_type_info(*rb2),
148 "restored pointer b2 not of correct type"
149 );
150
151 delete rb1;
152 delete rb2;
153}
154
155#ifdef BOOST_WINDOWS
156
157#define WIN32_LEAN_AND_MEAN
158#include <TCHAR.H>
159#include <windows.h>
160
161int
162test_main( int /* argc */, char* /* argv */[] )
163{
164 const char * testfile = boost::archive::tmpnam(NULL);
165 BOOST_REQUIRE(NULL != testfile);
166
167 HINSTANCE hDLL; // Handle to DLL
168 hDLL = LoadLibrary(_T("polymorphic_derived2.dll"));
169 BOOST_CHECK_MESSAGE(
170 (0 != hDLL),
171 "Failed to find/load polymorphic_derived2"
172 );
173 if(0 == hDLL)
174 return EXIT_FAILURE;
175
176 save_exported(testfile);
177 load_exported(testfile);
178 FreeLibrary(hDLL);
179
180 std::remove(testfile);
181 return EXIT_SUCCESS;
182}
183
184#else // presume *nix
185
186#include <dlfcn.h>
187
188int
189test_main( int /* argc */, char* /* argv */[] )
190{
191 const char * testfile = boost::archive::tmpnam(NULL);
192 BOOST_REQUIRE(NULL != testfile);
193
194 void * hDLL; // Handle to DLL
195 hDLL = dlopen(file: "polymorphic_derived2.so", RTLD_NOW | RTLD_GLOBAL);
196 BOOST_CHECK_MESSAGE((0 != hDLL), "Failed to find/load plugin_polymorphic_derived2" );
197 BOOST_CHECK_MESSAGE((0 != hDLL), dlerror() );
198 if(0 == hDLL)
199 return EXIT_FAILURE;
200
201 save_exported(testfile);
202 load_exported(testfile);
203 dlclose(handle: hDLL);
204
205 std::remove(filename: testfile);
206 return EXIT_SUCCESS;
207}
208
209#endif
210
211// EOF
212

source code of boost/libs/serialization/test/test_dll_plugin.cpp