473,385 Members | 1,944 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

object serialization

I'm looking for an example that would show how to serialize a c++
object at it's simplest w/o using any other api's. I have a class that
I want to serialize and then pass to my obj-c class so I can send it
over the wire.

I'm just looking for how to serialize it, then pack it back up on the
other end.

Any help much appreciated.

Apr 20 '07 #1
11 3630
Hi,

This is how I do it:

Derive every class from an ISerialize class.
This ISerialize class has one member accepting an IArchive i.e Serialize(
IArchive& Archive ).
The ISerialize class has a virtual function that returns it name (overridden
in the derived classes to return the class name). The name is used to
deserialize the correct class.

The IArchive function knows whether it is open for reading or writing.
The IArchive class has two virtual members read( char *, long length ) and a
similar write().
The IArchive also contains non virtual functions for all regular types like
string long int (use templates etc to reduce these to a few functions).
In addition this IArchive can serialize/deserialize ISerialize derived
classes by first storing there name and then calling the class'es Serialize
function passing itself. On deserialization it first reads the class name
(it knows this is a ISerialize class and not another type like long int etc.
because you pass a pointer or reference to it.)
Then it creates the object (lookup 'object factory' this is pretty standard
C++ way of creating objects by name or id) and calls the serialize member of
the object passing itself.

The Serialize member of a ISerialize derived typically (piece of my code)

void MCursor::MCursorInfo::Serialize( MArchive& Archive )
{
Archive.Serialize ( Event );
Archive.Serialize ( OffsetX );
Archive.Serialize ( OffsetY );
Archive.Serialize ( Animation );
}
Note1 that since the archive knows whether it is reading or writing it can
choose between the read or write function.
Note2 Because you can overload the read and write function you can create
derived function to store to memory disks, sockets etc easily. You only have
to overload the very simplistic read and write function.
Note3 Because (de)/serialization is done with one function it always is in
sync (no possibility to make a mismatch between read and write).

When this works extend your archive to keep track of written pointers to
ISerailize objects (so it only creates one object when it there are several
pointers around to one object on deserialization).
and add some stuff to automatically save STL vectors/sets/maps etc of
ISerialize etc

It might take some time to setup but ones you have it, it really works like
a charm :-) and loads of fun to see how easy it works then. I use it to save
my 2D game engines internal state (savegame) and load the same state back in
memory (deserialization).

Things to study:
Object factories
Lookup microsofts way of serialization on MSDN ( I stole the duplicate
pointer idea from them :-) )
Make sure your are reasonably aquainted with templates
Regards, Ron AF Greve

http://www.InformationSuperHighway.eu

"William" <Wi*******@gmail.comwrote in message
news:11**********************@d57g2000hsg.googlegr oups.com...
I'm looking for an example that would show how to serialize a c++
object at it's simplest w/o using any other api's. I have a class that
I want to serialize and then pass to my obj-c class so I can send it
over the wire.

I'm just looking for how to serialize it, then pack it back up on the
other end.

Any help much appreciated.

Apr 20 '07 #2
On Apr 20, 8:24 am, "Ron AF Greve" <ron@localhostwrote:
void MCursor::MCursorInfo::Serialize( MArchive& Archive )
{
Archive.Serialize ( Event );
Archive.Serialize ( OffsetX );
Archive.Serialize ( OffsetY );
Archive.Serialize ( Animation );

}
There is one extra complication that this approach doesn't address. As
the file format changes you need to be able to read old versions with
newer software.

There are a few ways of doing this. The way I've used in the past is
that each object also writes a schema number which can then be used to
work out which structure to use. You may get something that looks a
little more like this:

void MCursor::MCursorInfo::Serialize( MArchive& Archive )
{
int version = Archive.Version< MCursorInfo >( 2 );
if ( version >= 1 ) {
Archive.Serialize( Event );
Archive.Serialise( OffsetX );
Archive.Serialise( OffsetY );
}
if ( version >= 2 )
Archive.Serialise( Animation );
}

You want to arrange for Version to return the version that is to be
used. By passing in the type (I've done it via a template
specialisation, but there are other ways too) it can store a lookup
for overall file version against each schema part so that you can also
save to older file formats.
K

Apr 20 '07 #3
On Apr 20, 2:49 am, William <Wizumw...@gmail.comwrote:
I'm looking for an example that would show how to serialize a c++
object at it's simplest w/o using any other api's. I have a class that
I want to serialize and then pass to my obj-c class so I can send it
over the wire.
I'm just looking for how to serialize it, then pack it back up on the
other end.
There are, regretfully, no simple answers. Basically, you'll
have to either define a line protocol yourself, or use an
existing one, then code every type you use to conform to the
line protocol.

If there are no other particular constraints, I'd start with XDR
for the low level types, and build on it. I'd probably define a
oxdrstream and an ixdrstream, with << and >operators for the
primitive types. (Handling integers is easy. Floating point
less so; depending on how portable you want to code, it can even
be very complex.) More complex types then output each field.
(Some consideration must also be given to variable length types,
e.g. vectors and strings. XDR has some basic rules for these as
well.) And don't forget to follow pointers, if the pointed to
data is logically part of your object. (You cannot, of course,
serialize a pointer.)

You'll also have to give some thought to how the receiving end
will know what type it is getting. Depending on the protocol,
this may be more or less implicit, but most of the times, there
will be cases where you'll have to transmit this information as
well.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Apr 20 '07 #4
On 20 Apr 2007 00:52:40 -0700, James Kanze wrote:
>If there are no other particular constraints, I'd start with XDR
for the low level types, and build on it. I'd probably define a
oxdrstream and an ixdrstream, with << and >operators for the
primitive types.
Jack W. Reeves developed that kind of XDR library in a series of
articles (which may be found on the internet).
--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch
Apr 20 '07 #5
On 19 Apr 2007 17:49:46 -0700, William <Wi*******@gmail.comwrote:
>I'm looking for an example that would show how to serialize a c++
object at it's simplest w/o using any other api's. I have a class that
I want to serialize and then pass to my obj-c class so I can send it
over the wire.
Read the C++ FAQ-Lite.
>I'm just looking for how to serialize it, then pack it back up on the
other end.
Why not just write the data in some data format? Serialization seems
to be the wrong level of abstraction, not only in C++ but also in
other languages. Convert your data to a readable maybe even
standardized format and the receivers will be happy.
--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch
Apr 20 '07 #6
Hi Kirit,

Thanks for the reply and noting I missed something important.

Actually I have a number assigned to the complete archive. However I don't
use it anywhere since I couldn't really decide if it was better to have a
version per object or just change the archive version when one or more
objects change and then use if( Archive.GetVersion() ) or something like
that.

However looking at your example I realize that it would indeed be better to
do it on a 'per object' basis.

Regards, Ron AF Greve

http://www.InformationSuperHighway.eu

"Kirit Sælensminde" <ki****************@gmail.comwrote in message
news:11*********************@d57g2000hsg.googlegro ups.com...
On Apr 20, 8:24 am, "Ron AF Greve" <ron@localhostwrote:
>void MCursor::MCursorInfo::Serialize( MArchive& Archive )
{
Archive.Serialize ( Event );
Archive.Serialize ( OffsetX );
Archive.Serialize ( OffsetY );
Archive.Serialize ( Animation );

}

There is one extra complication that this approach doesn't address. As
the file format changes you need to be able to read old versions with
newer software.

There are a few ways of doing this. The way I've used in the past is
that each object also writes a schema number which can then be used to
work out which structure to use. You may get something that looks a
little more like this:

void MCursor::MCursorInfo::Serialize( MArchive& Archive )
{
int version = Archive.Version< MCursorInfo >( 2 );
if ( version >= 1 ) {
Archive.Serialize( Event );
Archive.Serialise( OffsetX );
Archive.Serialise( OffsetY );
}
if ( version >= 2 )
Archive.Serialise( Animation );
}

You want to arrange for Version to return the version that is to be
used. By passing in the type (I've done it via a template
specialisation, but there are other ways too) it can store a lookup
for overall file version against each schema part so that you can also
save to older file formats.
K

Apr 20 '07 #7
Why not just write the data in some data format? Serialization seems
to be the wrong level of abstraction, not only in C++ but also in
other languages. Convert your data to a readable maybe even
standardized format and the receivers will be happy.
Well, I'm only doing it so I can pass the data from a process to a
thread I just launched. So it's all sorta in the same name space. It's
just my libraries are in C++ and I was hoping to serialize the data
nativly in c++ so that when I copy it into my obj-c objects, i've be
most of the way done w/ performance benefits.

I'll see if I can make this happen.

Apr 21 '07 #8
On Apr 21, 2:40 am, William <Wizumw...@gmail.comwrote:
Why not just write the data in some data format? Serialization seems
to be the wrong level of abstraction, not only in C++ but also in
other languages. Convert your data to a readable maybe even
standardized format and the receivers will be happy.
Well, I'm only doing it so I can pass the data from a process to a
thread I just launched.
If the two threads are in the same process, you don't need
serialization, since they share common memory. (You will need
to ensure synchronized access, however.)
So it's all sorta in the same name space. It's
just my libraries are in C++ and I was hoping to serialize the data
nativly in c++ so that when I copy it into my obj-c objects, i've be
most of the way done w/ performance benefits.
In fact, you're concerned with communicating between two
languages, rather than between two processes or machines.
That's a different kettle of fish entirely; depending on the
representations used, it can vary from trivial (from C++ to C)
to very complicated (C++ to Cobol, perhaps). Serialization is
one solution, of course, but it is rarely the simplest or the
most efficient. Basically, when going from language A to
language B:

-- If possible, use data with compatible formats. This is what
makes C++ to C work so well; C++ more or less requires a
large category of data types to have a format compatible
with C, so all you have to do is pass a pointer to it to the
C function.

-- Failing that, you'll have to convert the data somehow. The
conversions can be more or less complicated: when going from
C++ to Fortran, for example, most of the basic types (int,
float, etc.) will be compatible, so all you have to worry
about is the fact that all Fortran parameters are by
reference, that Fortran arrays are row major, rather
than column major (but that can possibly be handled just by
declaring them differently) and strings---Fortran's
character type is not generally compatible with either
std::string or char[]. If the target is Cobol, on the other
hand, you may end up having to convert double's to BCD, and
what have you.

-- Finally, of course, if you already have serialization
routings available in both languages, you can use them. Be
aware, however, that what this really means is converting
C++ date to a neutral, third format, and then converting
this format back to the format in the other language. And
that the neutral, third format conforms to a number of
constraints which generally make it less efficient to
convert to and from than other formats.

If the serialization is already present and handy in both
languages, or if it is or will be necessary anyway,
serialization is certainly an option to be considered.
Otherwise, however, it is by far the least efficient, both where
it always counts (your time and effort), and in terms of
performance.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Apr 21 '07 #9
On Apr 21, 6:03 am, "Ron AF Greve" <ron@localhostwrote:
Hi Kirit,

Thanks for the reply and noting I missed something important.

Actually I have a number assigned to the complete archive. However I don't
use it anywhere since I couldn't really decide if it was better to have a
version per object or just change the archive version when one or more
objects change and then use if( Archive.GetVersion() ) or something like
that.

However looking at your example I realize that it would indeed be better to
do it on a 'per object' basis.
Top posting is generally frowned upon here.

There is a trade-off with the version per object rather than version
per file. Clearly it is going to make the archive data larger, but
even in '95 when I wrote about serialisation in DDJ <http://
www.ddj.com/184409645?pgno=3the overhead was worth it. These object
numbers are especially important when you're in development because
the object layouts are going to change rather frequently.

There is a way around this. You can arrange for the archive to be
versioned and for final release builds you also arrange for
Archive.Version<>() to return the archive version number which you
make sure is a higher number than the version number you'd got up to
for any object. For the development round you then start jump above
this number for each object again.

Archives saved with development builds will therefore be bigger than
those saved with release builds, but they will be readable by the
software version that saved them or any later version (there are some
complications about object classes that are no longer in use, but the
details aren't too hard to work out).

As for the DDJ article, the code isn't really worth anything now. It
was written when template programming meant using C macros - ouch! The
ideas should still be relevant though.
K

Apr 22 '07 #10
Hi Kirit,

"Kirit Sælensminde" <ki****************@gmail.comwrote in message
news:11**********************@y5g2000hsa.googlegro ups.com...
On Apr 21, 6:03 am, "Ron AF Greve" <ron@localhostwrote:
>Hi Kirit,

Thanks for the reply and noting I missed something important.

Actually I have a number assigned to the complete archive. However I
don't
use it anywhere since I couldn't really decide if it was better to have a
version per object or just change the archive version when one or more
objects change and then use if( Archive.GetVersion() ) or something like
that.

However looking at your example I realize that it would indeed be better
to
do it on a 'per object' basis.

There is a trade-off with the version per object rather than version
per file. Clearly it is going to make the archive data larger, but
even in '95 when I wrote about serialisation in DDJ <http://
www.ddj.com/184409645?pgno=3the overhead was worth it. These object
numbers are especially important when you're in development because
the object layouts are going to change rather frequently.
Thanks for the article it is good to see different approaches. Though in my
case I like the superclass idea (I have a common superclass anyway since I
need it in the rest of the engine). As a note to the OP (in the superclass
approach anyway) pointers have to be tested for zero and if so on
saving/loading a zero is saved or loaded but (obviously) the, virtual,
Serialize member on the zero pointer shouldn't be called.
>
There is a way around this. You can arrange for the archive to be
versioned and for final release builds you also arrange for
Archive.Version<>() to return the archive version number which you
make sure is a higher number than the version number you'd got up to
for any object. For the development round you then start jump above
this number for each object again.

Archives saved with development builds will therefore be bigger than
those saved with release builds, but they will be readable by the
software version that saved them or any later version (there are some
complications about object classes that are no longer in use, but the
details aren't too hard to work out).
Ok, good idea, that would be best of both worlds..
As for the DDJ article, the code isn't really worth anything now. It
was written when template programming meant using C macros - ouch! The
ideas should still be relevant though.
K

Regards, Ron AF Greve

http://www.InformationSuperHighway.eu
Apr 22 '07 #11
If the two threads are in the same process, you don't need
serialization, since they share common memory. (You will need
to ensure synchronized access, however.)
That's one possibility, but since the user may modify these objects
while my thread is processing the copies, it really makes since to do
it this way.
In fact, you're concerned with communicating between two
languages, rather than between two processes or machines.
That's a different kettle of fish entirely; depending on the
representations used, it can vary from trivial (from C++ to C)
to very complicated (C++ to Cobol, perhaps). Serialization is
one solution, of course, but it is rarely the simplest or the
most efficient. Basically, when going from language A to
language B:

-- If possible, use data with compatible formats. This is what
makes C++ to C work so well; C++ more or less requires a
large category of data types to have a format compatible
with C, so all you have to do is pass a pointer to it to the
C function.
I'm going from C++ to obj-c, and the pointer would work except for the
reasons I state above.
>
-- Failing that, you'll have to convert the data somehow. The
conversions can be more or less complicated: when going from
C++ to Fortran, for example, most of the basic types (int,
float, etc.) will be compatible, so all you have to worry
about is the fact that all Fortran parameters are by
reference, that Fortran arrays are row major, rather
than column major (but that can possibly be handled just by
declaring them differently) and strings---Fortran's
character type is not generally compatible with either
std::string or char[]. If the target is Cobol, on the other
hand, you may end up having to convert double's to BCD, and
what have you.
Conversions should be easy from C++ to obj-c.
>
-- Finally, of course, if you already have serialization
routings available in both languages, you can use them. Be
aware, however, that what this really means is converting
C++ date to a neutral, third format, and then converting
this format back to the format in the other language. And
that the neutral, third format conforms to a number of
constraints which generally make it less efficient to
convert to and from than other formats.

If the serialization is already present and handy in both
languages, or if it is or will be necessary anyway,
serialization is certainly an option to be considered.
Otherwise, however, it is by far the least efficient, both where
it always counts (your time and effort), and in terms of
performance.
Understood.

Apr 26 '07 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Sabyasachi Basu | last post by:
Most C++ object serialization techniques are intrusive, that is they require all serializable classes need to have functions to stream in and stream out their contents. I came across...
12
by: Nimmi Srivastav | last post by:
Are there any design patterns for object serialization/deserialization in C++? Where can I find information pertaining to them? Can someone post some real coding examples please? I have a need...
1
by: Julia | last post by:
I am getting some obsolete warning when using XslTransform has any one have an example of loading XSL from memory and run it on an XML generated by object serialization? Thanks in advance
1
by: Jeff Louie | last post by:
In a caffeine inspired frenzy I have added printing and object serialization support to my sample C# Windows Form drawing program. http://www.geocities.com/jeff_louie/OOP/oop21.htm...
3
by: AVL | last post by:
Hi, I'm new to .net. I need some info on serialization. What is serialization? Why do we need it? Why objects need to be serialized if they need to be stored in session or viewstate?
1
by: Marja Ribbers-de Vroed | last post by:
I'm using classic ASP with VBscript and I would like to have a facility for XML object serialization, just like the Serializer object that is available in ASP.NET. Is there such a thing for classic...
2
by: V | last post by:
Hi, I am trying to ascertain if Object Serialization (binary or xml) has been improved (new classes, or new ways) from version 1.1 of the .net framework. I pretty much know how to do that in...
5
by: Hans-Jürgen Philippi | last post by:
Hi Group, I've defined a class with an 'ID' property, which is a GUID that is created at the time of the very first object instance creation. This member is not included when I serialize an...
0
by: Igor | last post by:
Hi everyone ! I have a problem with object serialization. I created web service with number of methods. One of them receives object of the next type: public class ObjectClass private szValue...
2
by: Ed Sutton | last post by:
Is there an attribute I can add to a public get/set property to prevent serialization? I am using auto-generated object serialization for a custom type in my webs service. Thanks in advance...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.