Re: [Boost-users] Serializing a char *
On Sat, Aug 30, 2008 at 11:12 AM, Robert Ramey <ramey@rrsd.com> wrote:
I'm suspecting that there is a confusion about how to seriailzation a pointer to a null terminated string. It's natural to want to do something like
char *p; ... p = "jsdkfjads" ... ar & p;
because the library syntax encourages one to think that way.
But in this case, one would want
save(... int i = strlen(p); ar << i; ar << binary_object(i, p); }
load(... int i; ar >> i; ar >> binary_object(i,p); }
How do we deal with the trailing null? In this example trailing null is not saved, and it is a good thing, but shouldn't we add it after loading?
This example should probably be ar << binary_object(i + 1, p); // etc Robert Ramey Basilevs wrote:
On Sat, Aug 30, 2008 at 11:12 AM, Robert Ramey <ramey@rrsd.com> wrote:
I'm suspecting that there is a confusion about how to seriailzation a pointer to a null terminated string. It's natural to want to do something like
char *p; ... p = "jsdkfjads" ... ar & p;
because the library syntax encourages one to think that way.
But in this case, one would want
save(... int i = strlen(p); ar << i; ar << binary_object(i, p); }
load(... int i; ar >> i; ar >> binary_object(i,p); }
How do we deal with the trailing null? In this example trailing null is not saved, and it is a good thing, but shouldn't we add it after loading?
Robert Ramey <ramey <at> rrsd.com> writes:
This example should probably be
ar << binary_object(i + 1, p); // etc
Robert Ramey
Basilevs wrote:
On Sat, Aug 30, 2008 at 11:12 AM, Robert Ramey <ramey <at> rrsd.com> wrote:
I'm suspecting that there is a confusion about how to seriailzation a pointer to a null terminated string. It's natural to want to do something like
char *p; ... p = "jsdkfjads" ... ar & p;
because the library syntax encourages one to think that way.
But in this case, one would want
save(... int i = strlen(p); ar << i; ar << binary_object(i, p); }
load(... int i; ar >> i; ar >> binary_object(i,p); }
How do we deal with the trailing null? In this example trailing null is not saved, and it is a good thing, but shouldn't we add it after loading?
Thank you for laying this out, it is exactly what I need. Is there a way to do this in a free serialize function rather than requiring save & load functions? I would like to write a serialize function for each of my structures up through the hierarchy, and it looks to me like if I write save/load functions for a structure in the middle then I will have to continue with that all the way through to the top. So I would like to be able to handle the null terminated string within the serialize function if that's possible. Thanks, Diane
Diane wrote:
looks to me like if I write save/load functions for a structure in the middle then I will have to continue with that all the way through to the top.
Not at all true. serialize is called at each point. If ..SPLIT is used then a standard serial.ize function is inserted whch calls save/load for that (and only that) structure. Robert Ramey
Robert Ramey <ramey <at> rrsd.com> writes:
Not at all true. serialize is called at each point. If ..SPLIT is used then a standard serial.ize function is inserted whch calls save/load for that (and only that) structure.
Robert Ramey
Awesome, thanks! I found a similar piece of code in greg_serialize.hpp that I'm trying to work from, but I get compile errors even if I'm not doing anything in save/load: error: call of overloaded `serialize(boost::archive::text_iarchive&, MYSTRSTRUCT&, const boost::serialization::version_type&)' is ambiguous Is there any chance you can spot what I'm doing wrong in my code? typedef struct MYSTRSTRUCT { char *chstar; } MYSTRSTRUCT; BOOST_SERIALIZATION_SPLIT_FREE(MYSTRSTRUCT) template<class Archive> inline void serialize(Archive & ar, MYSTRSTRUCT & d, const unsigned int file_version) { split_free(ar, d, file_version); } template<class Archive> void save(Archive & ar, const MYSTRSTRUCT & d, unsigned int /* version */) { int i = strlen(d.chstar); } template<class Archive> void load(Archive & ar, MYSTRSTRUCT & d, unsigned int /*version*/) { int i; } And then it's used in serialize() for the struct that contains a MYSTRSTRUCT: ar & it.strstruct Here's the full compiler output: boost_1_36_0/boost/serialization/serialization.hpp: In function `void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = MYSTRSTRUCT]': boost_1_36_0/boost/archive/detail/iserializer.hpp:152: instantiated from `void boost::archive::detail::iserializer<Archive, T>::load_object_data(boost::archive::detail::basic_iarchive&, void*, unsigned int) const [with Archive = boost::archive::text_iarchive, T = MYSTRSTRUCT]' serialize4.cpp:80: instantiated from here boost_1_36_0/boost/serialization/serialization.hpp:133: error: call of overloaded `serialize(boost::archive::text_iarchive&, MYSTRSTRUCT&, const boost::serialization::version_type&)' is ambiguous boost_1_36_0/boost/serialization/serialization.hpp:73: note: candidates are: void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = MYSTRSTRUCT] serialize4.cpp:337: note: void boost::serialization::serialize(Archive&, MYSTRSTRUCT&, unsigned int) [with Archive = boost::archive::text_iarchive] serialize4.cpp:345: note: void serialize(Archive&, MYSTRSTRUCT&, unsigned int) [with Archive = boost::archive::text_iarchive] boost_1_36_0/boost/serialization/serialization.hpp: In function `void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = MYSTRSTRUCT]': boost_1_36_0/boost/archive/detail/oserializer.hpp:144: instantiated from `void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void* const [with Archive = boost::archive::text_oarchive, T = MYSTRSTRUCT]' serialize4.cpp:80: instantiated from here boost_1_36_0/boost/serialization/serialization.hpp:133: error: call of overloaded `serialize(boost::archive::text_oarchive&, MYSTRSTRUCT&, const boost::serialization::version_type&)' is ambiguous boost_1_36_0/boost/serialization/serialization.hpp:73: note: candidates are: void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = MYSTRSTRUCT] serialize4.cpp:337: note: void boost::serialization::serialize(Archive&, MYSTRSTRUCT&, unsigned int) [with Archive = boost::archive::text_oarchive] serialize4.cpp:345: note: void serialize(Archive&, MYSTRSTRUCT&, unsigned int) [with Archive = boost::archive::text_oarchive] Thanks, Diane
Look at the definition of the macros .. SPLIT_FREE. It defines a serialization function in terms of save/load. So defining your own serializaton function is redundant (and ambiguous) Robert Ramey Diane wrote:
Robert Ramey <ramey <at> rrsd.com> writes:
Not at all true. serialize is called at each point. If ..SPLIT is used then a standard serial.ize function is inserted whch calls save/load for that (and only that) structure.
Robert Ramey
Awesome, thanks!
I found a similar piece of code in greg_serialize.hpp that I'm trying to work from, but I get compile errors even if I'm not doing anything in save/load:
error: call of overloaded `serialize(boost::archive::text_iarchive&, MYSTRSTRUCT&, const boost::serialization::version_type&)' is ambiguous
Is there any chance you can spot what I'm doing wrong in my code?
typedef struct MYSTRSTRUCT { char *chstar; } MYSTRSTRUCT;
BOOST_SERIALIZATION_SPLIT_FREE(MYSTRSTRUCT)
template<class Archive> inline void serialize(Archive & ar, MYSTRSTRUCT & d, const unsigned int file_version) { split_free(ar, d, file_version); }
template<class Archive> void save(Archive & ar, const MYSTRSTRUCT & d, unsigned int /* version */) { int i = strlen(d.chstar); }
template<class Archive> void load(Archive & ar, MYSTRSTRUCT & d, unsigned int /*version*/) { int i; }
And then it's used in serialize() for the struct that contains a MYSTRSTRUCT: ar & it.strstruct
Here's the full compiler output: boost_1_36_0/boost/serialization/serialization.hpp: In function `void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = MYSTRSTRUCT]': boost_1_36_0/boost/archive/detail/iserializer.hpp:152: instantiated from `void boost::archive::detail::iserializer<Archive,
load_object_data(boost::archive::detail::basic_iarchive&, void*, unsigned int) const [with Archive = boost::archive::text_iarchive, T = MYSTRSTRUCT]' serialize4.cpp:80: instantiated from here boost_1_36_0/boost/serialization/serialization.hpp:133: error: call of overloaded `serialize(boost::archive::text_iarchive&, MYSTRSTRUCT&, const boost::serialization::version_type&)' is ambiguous boost_1_36_0/boost/serialization/serialization.hpp:73: note: candidates are: void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = MYSTRSTRUCT] serialize4.cpp:337: note: void boost::serialization::serialize(Archive&, MYSTRSTRUCT&, unsigned int) [with Archive = boost::archive::text_iarchive] serialize4.cpp:345: note: void serialize(Archive&, MYSTRSTRUCT&, unsigned int) [with Archive = boost::archive::text_iarchive] boost_1_36_0/boost/serialization/serialization.hpp: In function `void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = MYSTRSTRUCT]': boost_1_36_0/boost/archive/detail/oserializer.hpp:144: instantiated from `void boost::archive::detail::oserializer<Archive, save_object_data(boost::archive::detail::basic_oarchive&, const void* const [with Archive = boost::archive::text_oarchive, T = MYSTRSTRUCT]' serialize4.cpp:80: instantiated from here boost_1_36_0/boost/serialization/serialization.hpp:133: error: call of overloaded `serialize(boost::archive::text_oarchive&, MYSTRSTRUCT&, const boost::serialization::version_type&)' is ambiguous boost_1_36_0/boost/serialization/serialization.hpp:73: note: candidates are: void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = MYSTRSTRUCT] serialize4.cpp:337: note: void boost::serialization::serialize(Archive&, MYSTRSTRUCT&, unsigned int) [with Archive = boost::archive::text_oarchive] serialize4.cpp:345: note: void serialize(Archive&, MYSTRSTRUCT&, unsigned int) [with Archive = boost::archive::text_oarchive]
Thanks, Diane
participants (3)
-
Basilevs
-
Diane
-
Robert Ramey