]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/serialization/doc/special.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / serialization / doc / special.html
1 <!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2 <html>
3 <!--
4 (C) Copyright 2002-4 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 <head>
10 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
11 <link rel="stylesheet" type="text/css" href="../../../boost.css">
12 <link rel="stylesheet" type="text/css" href="style.css">
13 <title>Serialization - Special Considerations</title>
14 </head>
15 <body link="#0000ff" vlink="#800080">
16 <table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
17 <tr>
18 <td valign="top" width="300">
19 <h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
20 </td>
21 <td valign="top">
22 <h1 align="center">Serialization</h1>
23 <h2 align="center">Special Considerations</h2>
24 </td>
25 </tr>
26 </table>
27 <hr>
28 <dl class="page-index">
29 <dt><a href="#objecttracking">Object Tracking</a>
30 <dt><a href="#classinfo">Class Information</a>
31 <dt><a href="#helpersupport">Helper Support</a>
32 <dt><a href="#portability">Archive Portability</a>
33 <dl class="page-index">
34 <dt><a href="#numerics">Numerics</a>
35 <dt><a href="#traits">Traits</a>
36 </dl>
37 <dt><a href="#binary_archives">Binary Archives</a>
38 <dt><a href="#xml_archives">XML Archives</a>
39 <dt><a href="#export">Exporting Class Serialization</a>
40 <dt><a href="#static_libraries">Static Libraries and Serialization</a>
41 <dt><a href="#dlls">DLLS - Serialization and Runtime Linking</a>
42 <dt><a href="#plugins">Plugins</a>
43 <dt><a href="#multi_threading">Multi-Threading</a>
44 <dt><a href="#optimizations">Optimizations</a>
45 <dt><a href="exceptions.html">Archive Exceptions</a>
46 <dt><a href="exception_safety.html">Exception Safety</a>
47 </dl>
48
49 <h3><a name="objecttracking">Object Tracking</a></h3>
50 Depending on how the class is used and other factors, serialized objects
51 may be tracked by memory address. This prevents the same object from being
52 written to or read from an archive multiple times. These stored addresses
53 can also be used to delete objects created during a loading process
54 that has been interrupted by throwing of an exception.
55 <p>
56 This could cause problems in
57 progams where the copies of different objects are saved from the same address.
58 <pre><code>
59 template&lt;class Archive&gt;
60 void save(boost::basic_oarchive &amp; ar, const unsigned int version) const
61 {
62 for(int i = 0; i &lt; 10; ++i){
63 A x = a[i];
64 ar &lt;&lt; x;
65 }
66 }
67 </code></pre>
68 In this case, the data to be saved exists on the stack. Each iteration
69 of the loop updates the value on the stack. So although the data changes
70 each iteration, the address of the data doesn't. If a[i] is an array of
71 objects being tracked by memory address, the library will skip storing
72 objects after the first as it will be assumed that objects at the same address
73 are really the same object.
74 <p>
75 To help detect such cases, output archive operators expect to be passed
76 <code style="white-space: normal">const</code> reference arguments.
77 <p>
78 Given this, the above code will invoke a compile time assertion.
79 The obvious fix in this example is to use
80 <pre><code>
81 template&lt;class Archive&gt;
82 void save(boost::basic_oarchive &amp; ar, const unsigned int version) const
83 {
84 for(int i = 0; i &lt; 10; ++i){
85 ar &lt;&lt; a[i];
86 }
87 }
88 </code></pre>
89 which will compile and run without problem.
90 The usage of <code style="white-space: normal">const</code> by the output archive operators
91 will ensure that the process of serialization doesn't
92 change the state of the objects being serialized. An attempt to do this
93 would constitute augmentation of the concept of saving of state with
94 some sort of non-obvious side effect. This would almost surely be a mistake
95 and a likely source of very subtle bugs.
96 <p>
97 Unfortunately, implementation issues currently prevent the detection of this kind of
98 error when the data item is wrapped as a name-value pair.
99 <p>
100 A similar problem can occur when different objects are loaded to an address
101 which is different from the final location:
102 <pre><code>
103 template&lt;class Archive&gt;
104 void load(boost::basic_oarchive &amp; ar, const unsigned int version) const
105 {
106 for(int i = 0; i &lt; 10; ++i){
107 A x;
108 ar &gt;&gt; x;
109 std::m_set.insert(x);
110 }
111 }
112 </code></pre>
113 In this case, the address of <code>x</code> is the one that is tracked rather than
114 the address of the new item added to the set. Left unaddressed
115 this will break the features that depend on tracking such as loading an object through a pointer.
116 Subtle bugs will be introduced into the program. This can be
117 addressed by altering the above code thusly:
118
119 <pre><code>
120 template&lt;class Archive&gt;
121 void load(boost::basic_iarchive &amp; ar, const unsigned int version) const
122 {
123 for(int i = 0; i &lt; 10; ++i){
124 A x;
125 ar &gt;&gt; x;
126 std::pair&lt;std::set::const_iterator, bool&gt; result;
127 result = std::m_set.insert(x);
128 ar.reset_object_address(& (*result.first), &x);
129 }
130 }
131 </code></pre>
132 This will adjust the tracking information to reflect the final resting place of
133 the moved variable and thereby rectify the above problem.
134 <p>
135 If it is known a priori that no pointer
136 values are duplicated, overhead associated with object tracking can
137 be eliminated by setting the object tracking class serialization trait
138 appropriately.
139 <p>
140 By default, data types designated primitive by the
141 <a target="detail" href="traits.html#level">Implementation Level</a>
142 class serialization trait are never tracked. If it is desired to
143 track a shared primitive object through a pointer (e.g. a
144 <code style="white-space: normal">long</code> used as a reference count), It should be wrapped
145 in a class/struct so that it is an identifiable type.
146 The alternative of changing the implementation level of a <code style="white-space: normal">long</code>
147 would affect all <code style="white-space: normal">long</code>s serialized in the whole
148 program - probably not what one would intend.
149 <p>
150 It is possible that we may want to track addresses even though
151 the object is never serialized through a pointer. For example,
152 a virtual base class need be saved/loaded only once. By setting
153 this serialization trait to <code style="white-space: normal">track_always</code>, we can suppress
154 redundant save/load operations.
155 <pre><code>
156 BOOST_CLASS_TRACKING(my_virtual_base_class, boost::serialization::track_always)
157 </code></pre>
158
159 <h3><a name="helpersupport">Helper Support</a></h3>
160 Some types, specially those with complicated lifetime behavior or limited
161 access to their internal state, might need or benefit from elaborate serialization
162 algorithms. The prinicple motivating case is that of shared_ptr. As instances
163 are loaded, they have to be "matched up" with any other instances which have
164 already been loaded. Thus, a table of previously loaded instances has to be
165 maintained while the archive containing the shared_ptr instances is being loaded.
166 Without maintaining such a table, the shared_ptr would be a serializable type.
167 <p>
168 To implement this facility, one declares a <i>helper object</i>
169 associated to the current archive that can be used to store contextual
170 information relevant to the particular type serialization algorithm.
171
172 <pre><code>
173 template<class T>
174 class shared_ptr
175 {
176 ...
177 };
178
179 BOOST_SERIALIZATION_SPLIT_FREE(shared_ptr)
180
181 class shared_ptr_serialization_helper
182 {
183 // table of previously loaded shared_ptr
184 // lookup a shared_ptr from the object address
185 shared_ptr<T> lookup(const T *);
186 // insert a new shared_ptr
187 void insert<shared_ptr<T> >(const shared_ptr<T> *);
188 };
189
190 namespace boost {
191 namespace serialization {
192
193 template&lt;class Archive&gt;
194 void save(Archive &amp; ar, const shared_ptr &amp; x, const unsigned int /* version */)
195 {
196 // save shared ptr
197 ...
198 }
199
200 template&lt;class Archive&gt;
201 void load(Archive &amp; ar, shared_ptr &amp; x, const unsigned int /* version */)
202 {
203 // get a unique identifier. Using a constant means that all shared pointers
204 // are held in the same set. Thus we detect handle multiple pointers to the
205 // same value instances in the archive.
206 const void * shared_ptr_helper_id = 0;
207
208 shared_ptr_serialization_helper &amp; hlp =
209 ar.template get_helper&lt;shared_ptr_serialization_helper&gt;(helper_instance_id);
210
211 // load shared pointer object
212 ...
213
214 shared_ptr_serialization_helper &amp; hlp =
215 ar.template get_helper&lt;shared_ptr_serialization_helper&gt;(shared_ptr_helper_id);
216
217 // look up object in helper object
218 T * shared_object hlp.lookup(...);
219
220 // if found, return the one from the table
221
222 // load the shared_ptr data
223 shared_ptr<T> sp = ...
224
225 // and add it to the table
226 hlp.insert(sp);
227 // implement shared_ptr_serialization_helper load algorithm with the aid of hlp
228 }
229
230 } // namespace serialization
231 } // namespace boost
232 </code></pre>
233 <code style="white-space: normal">get_helper&lt;shared_ptr_serialization_helper&gt;();</code>
234 creates a helper object associated to the archive the first time it is invoked;
235 subsequent invocations return a reference to the object created in the first
236 place, so that <code style="white-space: normal">hlp</code> can effectively be
237 used to store contextual information persisting through the serialization
238 of different <code style="white-space: normal">complex_type</code> objects on
239 the same archive.
240
241 <p>
242 Helpers may be created for saving and loading archives.
243 The same program might have several different helpers or the same helper instantiated
244 separately from different parts of the program. This is what makes the helper_instance_id
245 necessary. In principle it could be any unique integer. In practice it seems
246 easiest to use the address of the serialization function which contains it. The
247 above example uses this technique.
248
249 <h3><a name="classinfo">Class Information</a></h3>
250 By default, for each class serialized, class information is written to the archive.
251 This information includes version number, implementation level and tracking
252 behavior. This is necessary so that the archive can be correctly
253 deserialized even if a subsequent version of the program changes
254 some of the current trait values for a class. The space overhead for
255 this data is minimal. There is a little bit of runtime overhead
256 since each class has to be checked to see if it has already had its
257 class information included in the archive. In some cases, even this
258 might be considered too much. This extra overhead can be eliminated
259 by setting the
260 <a target="detail" href="traits.html#level">implementation level</a>
261 class trait to: <code style="white-space: normal">boost::serialization::object_serializable</code>.
262 <p>
263 <i>Turning off tracking and class information serialization will result
264 in pure template inline code that in principle could be optimised down
265 to a simple stream write/read.</i> Elimination of all serialization overhead
266 in this manner comes at a cost. Once archives are released to users, the
267 class serialization traits cannot be changed without invalidating the old
268 archives. Including the class information in the archive assures us
269 that they will be readable in the future even if the class definition
270 is revised. A light weight structure such as a display pixel might be
271 declared in a header like this:
272
273 <pre><code>
274 #include &lt;boost/serialization/serialization.hpp&gt;
275 #include &lt;boost/serialization/level.hpp&gt;
276 #include &lt;boost/serialization/tracking.hpp&gt;
277
278 // a pixel is a light weight struct which is used in great numbers.
279 struct pixel
280 {
281 unsigned char red, green, blue;
282 template&lt;class Archive&gt;
283 void serialize(Archive &amp; ar, const unsigned int /* version */){
284 ar &lt;&lt; red &lt;&lt; green &lt;&lt; blue;
285 }
286 };
287
288 // elminate serialization overhead at the cost of
289 // never being able to increase the version.
290 BOOST_CLASS_IMPLEMENTATION(pixel, boost::serialization::object_serializable);
291
292 // eliminate object tracking (even if serialized through a pointer)
293 // at the risk of a programming error creating duplicate objects.
294 BOOST_CLASS_TRACKING(pixel, boost::serialization::track_never)
295 </code></pre>
296
297 <h3><a name="portability">Archive Portability</a></h3>
298 Several archive classes create their data in the form of text or a portable binary format.
299 It should be possible to save such a class on one platform and load it on another.
300 This is subject to a couple of conditions.
301 <h4><a name="numerics">Numerics</a></h4>
302 The architecture of the machine reading the archive must be able hold the data
303 saved. For example, the gcc compiler reserves 4 bytes to store a variable of type
304 <code style="white-space: normal">wchar_t</code> while other compilers reserve only 2 bytes.
305 So it's possible that a value could be written that couldn't be represented by the loading program. This is a
306 fairly obvious situation and easily handled by using the numeric types in
307 <a target="cstding" href="../../../boost/cstdint.hpp">&lt;boost/cstdint.hpp&gt;</a>
308 <P>
309 A special integral type is <code>std::size_t</code> which is a typedef
310 of an integral types guaranteed to be large enough
311 to hold the size of any collection, but its actual size can differ depending
312 on the platform. The
313 <a href="wrappers.html#collection_size_type"><code>collection_size_type</code></a>
314 wrapper exists to enable a portable serialization of collection sizes by an archive.
315 Recommended choices for a portable serialization of collection sizes are to
316 use either 64-bit or variable length integer representation.
317
318
319 <h4><a name="traits">Traits</a></h4>
320 Another potential problem is illustrated by the following example:
321 <pre><code>
322 template&lt;class T&gt;
323 struct my_wrapper {
324 template&lt;class Archive&gt;
325 Archive & serialize ...
326 };
327
328 ...
329
330 class my_class {
331 wchar_t a;
332 short unsigned b;
333 template&lt;class Archive&gt;
334 Archive & serialize(Archive & ar, unsigned int version){
335 ar & my_wrapper(a);
336 ar & my_wrapper(b);
337 }
338 };
339 </code></pre>
340 If <code style="white-space: normal">my_wrapper</code> uses default serialization
341 traits there could be a problem. With the default traits, each time a new type is
342 added to the archive, bookkeeping information is added. So in this example, the
343 archive would include such bookkeeping information for
344 <code style="white-space: normal">my_wrapper&lt;wchar_t&gt;</code> and for
345 <code style="white-space: normal">my_wrapper&lt;short_unsigned&gt;</code>.
346 Or would it? What about compilers that treat
347 <code style="white-space: normal">wchar_t</code> as a
348 synonym for <code style="white-space: normal">unsigned short</code>?
349 In this case there is only one distinct type - not two. If archives are passed between
350 programs with compilers that differ in their treatment
351 of <code style="white-space: normal">wchar_t</code> the load operation will fail
352 in a catastrophic way.
353 <p>
354 One remedy for this is to assign serialization traits to the template
355 <code style="white-space: normal">my_template</code> such that class
356 information for instantiations of this template is never serialized. This
357 process is described <a target="detail" href="traits.html#templates">above</a> and
358 has been used for <a target="detail" href="wrappers.html#nvp"><strong>Name-Value Pairs</strong></a>.
359 Wrappers would typically be assigned such traits.
360 <p>
361 Another way to avoid this problem is to assign serialization traits
362 to all specializations of the template <code style="white-space: normal">my_wrapper</code>
363 for all primitive types so that class information is never saved. This is what has
364 been done for our implementation of serializations for STL collections.
365
366 <h3><a name="binary_archives">Binary Archives</a></h3>
367 Standard stream i/o on some systems will expand linefeed characters to carriage-return/linefeed
368 on output. This creates a problem for binary archives. The easiest way to handle this is to
369 open streams for binary archives in "binary mode" by using the flag
370 <code style="white-space: normal">ios::binary</code>. If this is not done, the archive generated
371 will be unreadable.
372 <p>
373 Unfortunately, no way has been found to detect this error before loading the archive. Debug builds
374 will assert when this is detected so that may be helpful in catching this error.
375
376 <h3><a name="xml_archives">XML Archives</a></h3>
377 XML archives present a somewhat special case.
378 XML format has a nested structure that maps well to the "recursive class member visitor" pattern
379 used by the serialization system. However, XML differs from other formats in that it
380 requires a name for each data member. Our goal is to add this information to the
381 class serialization specification while still permiting the the serialization code to be
382 used with any archive. This is achived by requiring that all data serialized to an XML archive
383 be serialized as a <a target="detail" href="wrappers.html#nvp">name-value pair</a>.
384 The first member is the name to be used as the XML tag for the
385 data item while the second is a reference to the data item itself. Any attempt to serialize data
386 not wrapped in a in a <a target="detail" href="wrappers.html#nvp">name-value pair</a> will
387 be trapped at compile time. The system is implemented in such a way that for other archive classes,
388 just the value portion of the data is serialized. The name portion is discarded during compilation.
389 So by always using <a target="detail" href="wrappers.html#nvp">name-value pairs</a>, it will
390 be guaranteed that all data can be serialized to all archive classes with maximum efficiency.
391
392 <h3><a name="export">Exporting Class Serialization</a></h3>
393 <a target="detail" href="traits.html#export">Elsewhere</a> in this manual, we have described
394 <code style="white-space: normal">BOOST_CLASS_EXPORT</code>.
395 Export implies two things:
396 <ul>
397 <li>Instantiates code which is not otherwise referred to.
398 <li>Associates an external identifier with the class to be serialized.
399 The fact that the class isn't explicitly referred to implies this
400 requirement.
401 </ul>
402 In C++, usage of code not explicitly referred to is implemented via
403 virtual functions. Hence, the need for export is implied by the
404 usage of a derived class that is manipulated via a pointer or
405 reference to its base class.
406
407 <p>
408 <code style="white-space: normal">BOOST_CLASS_EXPORT</code> in the same
409 source module that includes any of the archive class headers will
410 instantiate code required to serialize polymorphic pointers of
411 the indicated type to the all those archive classes. If no
412 archive class headers are included, then no code will be instantiated.
413
414 <p>
415 Note that the implemenation of this functionality requires
416 that the <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
417 macro appear <b>after</b> the inclusion of any archive
418 class headers for which code is to be instantiated.
419 So, code that uses <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
420 will look like the following:
421 <pre><code>
422 #include &lt;boost/archive/text_oarchive.hpp&gt;
423 #include &lt;boost/archive/text_oarchive.hpp&gt;
424 ... // other archives
425
426 #include "a.hpp" // header declaration for class a
427 BOOST_CLASS_EXPORT(a)
428 ... // other class headers and exports
429 </code></pre>
430 This will be true regardless of whether the code is part
431 of a stand alone executable, a static library or
432 a dyanmic or shared library.
433 <p>
434 Including
435 <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
436 in the "a.hpp" header itself as one would do with
437 other serialization traits will make it difficult
438 or impossible to follow the rule above regarding
439 inclusion of archive headers before
440 <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
441 is invoked. This can best be addressed by using
442 <code style="white-space: normal">BOOST_CLASS_EXPORT_KEY</code>
443 in the header declarations and
444 <code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT</code>
445 in the class definition file.
446
447 <p>
448 This system has certain implications for placing code in static or shared
449 libraries. Placing <code style="white-space: normal">BOOST_CLASS_EXPORT</code>
450 in library code will have no effect unless archive class headers are
451 also included. So when building a library, one should include all headers
452 for all the archive classes which he anticipates using. Alternatively,
453 one can include headers for just the
454 <a href="archive_reference.html#polymorphic">Polymoprhic Archives</a>.
455
456 <p>
457 Strictly speaking, export should not be necessary if all pointer serialization
458 occurs through the most derived class. However, in order to detect
459 what would be a catastophic error, the library traps ALL serializations through
460 a pointer to a polymorphic class which are not exported or otherwise registered.
461 So, in practice, be prepared to register or export all classes with one
462 or more virtual functions which are serialized through a pointer.
463
464 <p>
465 Note that the implementation of this functionality depends upon vendor
466 specific extensions to the C++ language. So, there is no guaranteed portability
467 of programs which use this facility. However, all C++ compilers which
468 are tested with boost provide the required extensions. The library
469 includes the extra declarations required by each of these compilers.
470 It's reasonable to expect that future C++ compilers will support
471 these extensions or something equivalent.
472
473 <h3><a name="static_libraries">Static Libraries and Serialization</a></h3>
474 Code for serialization of data types can be saved in libraries
475 just as it can for the rest of the type implementation.
476 This works well, and can save a huge amount of compilation time.
477 <ul>
478 <li>Only compile serialization definitions in the library.
479 <li>Explicitly instantiate serialization code for ALL
480 archive classes you intend to use in the library.
481 <li>For exported types, only use <code style="white-space: normal">BOOST_CLASS_EXPORT_KEY</code>
482 in headers.
483 <li>For exported types, only use <code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT</code>
484 in definitions compiled in the library. For any particular type,
485 there should be only one file which contains
486 <code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT</code>
487 for that type. This ensures that only one copy
488 of serialization code will exist within the program. It avoids
489 wasted space and the possibility of having different
490 versions of the serialization code in the same program.
491 Including
492 <code style="white-space: normal">BOOST_CLASS_EXPORT_IMPLEMENT</code>
493 in multiple files could result in a failure
494 to link due to duplicated symbols or the throwing
495 of a runtime exception.
496 <li> Code for serialization should be only in the library,
497 <li>Familiarize yourself with the <b>PIMPL</b> idiom.
498 </ul>
499 This is illustrated by
500 <a href = "../example/demo_pimpl.cpp" target="demo_pimpl">
501 <code style="white-space: normal">demo_pimpl.cpp</code>
502 </a>,
503 <a href = "../example/demo_pimpl_A.cpp" target="demo_pimpl">
504 <code style="white-space: normal">demo_pimpl_A.cpp</code>
505 </a>
506 and
507 <a href = "../example/demo_pimpl_A.hpp" target="demo_pimpl">
508 <code style="white-space: normal">demo_pimpl_A.hpp</code>
509 </a>
510 where implementation of serializaton is in a static library
511 completely separate from the main program.
512
513 <h3><a name="dlls">DLLS - Serialization and Runtime Linking</a></h3>
514 Serialization code can be placed in libraries to be linked at runtime. That is,
515 code can be placed in DLLS(Windows) Shared Libraries(*nix), or static libraries
516 as well as the main executable. The best technique is the
517 same as that described above for libraries. The serialization
518 library test suite includes the following programs
519 to illustrate how this works:
520 <p>
521
522 <a href = "../test/test_dll_simple.cpp" target="test_dll_simple">
523 <code style="white-space: normal">test_dll_simple</code>
524 </a>,
525 and
526 <a href = "../test/dll_a.cpp" target="dll_a">
527 <code style="white-space: normal">dll_a.cpp</code>
528 </a>
529 where implementation of serializaton is also completely separate
530 from the main program but the code is loaded at runtime. In this
531 example, this code is loaded automatically when the program which
532 uses it starts up, but it could just as well be loaded and unloaded
533 with an OS dependent API call.
534 <p>
535 Also included are
536 <a href = "../test/test_dll_exported.cpp" target="test_dll_exported">
537 <code style="white-space: normal">test_dll_exported.cpp</code>
538 </a>,
539 and
540 <a href = "../test/polymorphic_derived2.cpp" target="polymorphic_derived2">
541 <code style="white-space: normal">polymorphic_derived2.cpp</code>
542 </a>
543 which are similar to the above but include tests of the export
544 and no_rtti facilities in the context of DLLS.
545 <p>
546 For best results, write your code to conform to the following
547 guidelines:
548 <ul>
549 <li>Don't include <code>inline</code> code in classes used in DLLS.
550 This will generate duplicate code in the DLLS and mainline. This
551 needlessly duplicates code. Worse, it makes is possible for
552 different versions of the same code to exist simultaneously. This
553 type of error turns out to be excruciatingly difficult to debug.
554 Finally, it opens the possibility that a module being referred to
555 might be explictly unloaded which would (hopefully) result in
556 a runtime error. This is another bug that is not always
557 reproducible or easy to find. For class member templates use something like
558
559 <pre><code>
560 template&lt;class Archive&gt;
561 void serialize(Archive & ar, const unsigned int version);
562 </code></pre>
563 in the header, and
564
565 <pre><code>
566 template&lt;class Archive&gt;
567 void myclass::serialize(Archive & ar, const unsigned int version){
568 ...
569 }
570
571 BOOST_EXPORT_CLASS_IMPLEMENT(my_class)
572
573 #include &lt;boost/archive/text_oarchive&gt;
574 #include &lt;boost/archive/text_iarchive&lt;
575 template myclass::serialize(boost::archive::text_oarchive & ar, const unsigned int version);
576 template myclass::serialize(boost::archive::text_iarchive & ar, const unsigned int version);
577 ... // repeat for each archive class to be used.
578 </code></pre>
579 in the implementation file. This will result in generation of all code
580 required in only one place. The library does not detect this type of error for you.
581 <li>If DLLS are to be loaded and unloaded explicitly (e.g. using <code>dlopen</code> in *nix or
582 <code>LoadLibrary</code> in Windows). Try to arrange that they are unloaded in the reverse
583 sequence. This should guarantee that problems are avoided even if the
584 above guideline hasn't been followed.
585
586 </ul>
587
588 <h3><a name="plugins">Plugins</a></h3>
589 In order to implement the library, various facilities for runtime
590 manipulation of types at runtime were required. These
591 are <a target="detail" href="extended_type_info.html"><code>extended_type_info</code></a>
592 for associating classes with external identifying strings (<b>GUID</b>)
593 and <a target="detail" href="void_cast.html"><code>void_cast</code></a>
594 for casting between pointers of related types.
595
596 To complete the functionality of
597 <a target="detail" href="extended_type_info.html"><code>extended_type_info</code></a>
598 the ability to construct and destroy corresponding types has been
599 added. In order to use this functionality, one must specify
600 how each type is created. This should be done at the time
601 a class is exported. So, a more complete example of the code above would be:
602
603 <pre><code>
604 #include &lt;boost/archive/text_oarchive.hpp&gt;
605 #include &lt;boost/archive/text_oarchive.hpp&gt;
606 ... // other archives
607
608 #include "a.hpp" // header declaration for class a
609
610 // this class has a default constructor
611 BOOST_SERIALIZATION_FACTORY_0(a)
612 // as well as one that takes one integer argument
613 BOOST_SERIALIZATION_FACTORY_1(a, int)
614
615 // specify the GUID for this class
616 BOOST_CLASS_EXPORT(a)
617 ... // other class headers and exports
618 </code></pre>
619
620 With this in place, one can construct, serialize and destroy a class
621 about which is known only the <b>GUID</b> and a base class.
622
623
624 <h3><a name="multi_threading">Multi-Threading</a></h3>
625 The fundamental purpose of serialization would conflict with multiple
626 threads concurrently writing/reading from/to a single open archive instance.
627 The library implementation presumes that the application avoids such a situtation.
628 <p>
629 However, Writing/Reading different archives simultaneously
630 in different tasks is permitted as each archive instance is (almost)
631 completely independent from any other archive instance. The only shared
632 information is some type tables which have been implemented using a
633 lock-free thread-safe
634 <a target="detail" href="singleton.html">
635 <code style="white-space: normal">singleton</code>
636 </a>
637 described elsewhere in this documentation.
638 <p>
639 This singleton implementation guarantees that all of this shared
640 information is initialized when the code module which contains
641 it is loaded. The serialization library takes care to
642 ensure that these data structures are not subsequently
643 modified. The only time there could be a problem would
644 be if code is loaded/unloaded while another task is
645 serializing data. This could only occur for types whose
646 serialization is implemented in a dynamically loaded/unloaded DLL
647 or shared library. So if the following is avoided:
648 <ul>
649 <li>Accessing the same archive instance from different tasks.
650 <li>Loading/Unloading DLLS or shared libraries while any archive
651 instances are open.
652 </ul>
653 The library should be thread safe.
654
655 <h3><a name="optimizations">Optimizations</a></h3>
656 In performance critical applications that serialize large sets of contiguous data of homogeneous
657 types one wants to avoid the overhead of serializing each element individually, which is
658 the motivation for the <a href="wrappers.html#arrays"><code>array</code></a>
659 wrapper.
660
661 Serialization functions for data types containing contiguous arrays of homogeneous
662 types, such as for <code>std::vector</code>, <code>std::valarray</code> or
663 <code>boost::multiarray</code> should serialize them using an
664 <a href="wrappers.html#arrays"><code>array</code></a> wrapper to make use of
665 these optimizations.
666
667 Archive types that can provide optimized serialization for contiguous arrays of
668 homogeneous types should implement these by overloading the serialization of
669 the <a href="wrappers.html#arrays"><code>array</code></a> wrapper, as is done
670 for the binary archives.
671
672
673 <h3><a href="exceptions.html">Archive Exceptions</a></h3>
674 <h3><a href="exception_safety.html">Exception Safety</a></h3>
675
676 <hr>
677 <p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
678 Distributed under the Boost Software License, Version 1.0. (See
679 accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
680 </i></p>
681 </body>
682 </html>