Topic: Marshalling C++ Objects
Author: ahr@cs.stir.ac.uk (Andrew H Randall (MSc/SE))
Date: 6 Mar 1995 10:27:33 GMT Raw View
In article <3ilajs$csu@argo.hks.com>, narsu@hks.com (Uttam Narsu) writes:
|> : . The best way (we think) is to make the
|> : objects straemable by inheriting them from a base class which offers the
|> : virtual interface such as CLASS::toStream and CLASS::fromStream, both take
|> : a Stream Reference as parameter and returning the Reference too. You also
|> : can use the operator>> or operator<< on the class, if you like.
[text omitted]
|> The only problem with the above approach is that you can't send
|> objects which contain const data members or references. For that,
|> you have to change the fromStream side to creating objects via
|> constructor calls. This becomes more difficult if you have cycles
|> in your objects.
|>
|>
|> --
|>
I have used Microsoft Foundation Classes, which implement something like this
(CObject is the base class; CArchive the stream class). This has the problem with
references and const members. However, it handles cycles very well - the object
remembers when it's stored to the archive, and if it is put in again, it writes a
reference to the copy which is already there. The upshot is that, transparently
to the programmer, you just dump an object to the stream without worrying if
you're getting into a loop of cross-references. Reading back is also without
problems. (I discovered this _after_ writing my own workaround to the problem!)
Author: Mark Little <M.C.Little@ncl.ac.uk>
Date: 28 Feb 1995 14:01:38 GMT Raw View
In article <3irb98$qj5@picasso.cssc-syd.tansu.com.au>, Greg Wilkins <gregw@ind.tansu.com.au> writes:
>tariqh@dcs.qmw.ac.uk (Tariq Hamid) wrote:
>>
>> How do you marshal/unmarshal C++ objects. It appears to be a difficult problem
>> as the inheritance hierarchy has to be considered.
>>
>
>There are several techniques for doing it in C++ code (with or
>without the assistance of horrid macros). But all a a bit manual
>and prone to some degree of error.
In Arjuna, which is a set of tools for building fault-tolerant distributed
applications in C++, we have a stub generation tool which automates a great deal
of this. It works on the standard C++ class definition, and generates marshalling/unmarshalling
code for fairly complex objects (lists of arbitrary complexity, other classes, etc),
and does this transparently. The only difference between using a local and remove object is
a single line change in the application (basically to include the stub header instead
of the real object).
Although manual intervention is possible and necessary in some cases, we've
found this to be a useful starting point, as have many people who've used the
system.
If anyone's interested in looking at this, the source for Arjuna can be obtained
via anonymous ftp from arjuna.ncl.ac.uk in /pub/Arjuna/Source. This is the whole
fault-tolerant system, which the stub generator is only a part of. It's still
possible to use it in isolation though.
If you're only interested in distributed C++, then drop me a line.
>
>Hopefully the standard for this will be IDL (CORBA), or some
>extension to it for OODBs (ODMG-93).
>
Certainly for portability and cross-language support, this will be
necessary.
Mark.
-------------------------------------------------------------------------
SENDER : Mark Little, PHONE : +44 91 222 8066, FAX : +44 91 222 8232
Arjuna Project, Distributed Systems Research.
POST : Department of Computing Science, University of Newcastle upon Tyne,
UK, NE1 7RU
ARPA : M.C.Little@newcastle.ac.uk
JANET : M.C.Little@uk.ac.newcastle
Author: Mark Little <M.C.Little@ncl.ac.uk>
Date: 1 Mar 1995 13:33:00 GMT Raw View
In article <N8a71c7w165w@sytex.com>, smcl@sytex.com (Scott McLoughlin) writes:
>Greg Wilkins <gregw@ind.tansu.com.au> writes:
>
>> tariqh@dcs.qmw.ac.uk (Tariq Hamid) wrote:
>> >
>> > How do you marshal/unmarshal C++ objects. It appears to be a difficult prob
>> > as the inheritance hierarchy has to be considered.
>> >
>>
>> There are several techniques for doing it in C++ code (with or
>> without the assistance of horrid macros). But all a a bit manual
>> and prone to some degree of error.
>>
>>
>
>Howdy,
> Regarding various techniques of "marshaling" C++ objects,
>do any (all?) of the techniques handle circular data structures/
>object identity? If so, I'd like pointers to literature and
>implementations.
The Arjuna stub generator (tatsu), deals with this. If you want to
read about it (and/or get the source), try ftp-ing to arjuna.ncl.ac.uk
and look in pub/Arjuna/PR3.0 and pub/Arjuna/Docs. Or, you can try
http://arjuna.ncl.ac.uk/
All the best,
Mark.
-------------------------------------------------------------------------
SENDER : Mark Little, PHONE : +44 91 222 8066, FAX : +44 91 222 8232
Arjuna Project, Distributed Systems Research.
POST : Department of Computing Science, University of Newcastle upon Tyne,
UK, NE1 7RU
ARPA : M.C.Little@newcastle.ac.uk
JANET : M.C.Little@uk.ac.newcastle
Author: scotc@meaddata.com (Scot Cunningham)
Date: 28 Feb 1995 21:04:54 GMT Raw View
Tariq Hamid (tariqh@dcs.qmw.ac.uk) wrote:
: How do you marshal/unmarshal C++ objects. It appears to be a difficult problem
: as the inheritance hierarchy has to be considered.
The way this is handled is for the objects to have marshall/unmarshall methods.
If there is inheritance involved, the children need to call the marshall/unmarshall
methods on their parents. The marshall/unmarshall methods save the data on the
object to a data buffer. Ideally, this data buffer is in the form of a stream.
Object relationships can get tricky too.
If two objects share a pointer to another common object, that relationship
needs to be preserved without duplicating the common object. I've heard it
called "preserving the morphology".
There are a few other issues to contend with as well.
To deal with marshalling/unmarshalling C++ objects, I've used
the Tools.h++ object library from Rogue Wave. They have an object library and
an excellent manual that deals with this subject. They also provide alot of
other useful objects unrelated to the marshall/unmarshall issue.
I've used their marshall/unmarshall (saveGuts/restoreGuts) in 3 tier
architectures with a good deal of success from both a development and
performance perspective. However, we did have to build a few supporting tools
to help us interface with the middle of the three tiers. That's another topic.
Scot Cunningham
CSC Consulting, Cincinnati OH
513 768-4440
Author: narsu@hks.com (Uttam Narsu)
Date: 24 Feb 1995 19:04:28 GMT Raw View
Koch Andres (cho11884@pax.eunet.ch) wrote:
: Tariq Hamid (tariqh@dcs.qmw.ac.uk) wrote:
: distributed processes with success. The best way (we think) is to make the
: objects straemable by inheriting them from a base class which offers the
: virtual interface such as CLASS::toStream and CLASS::fromStream, both take
: a Stream Reference as parameter and returning the Reference too. You also
: can use the operator>> or operator<< on the class, if you like.
: The transporting media class gets the Object to send, and creates a stream
: typically a streamable buffer, and then calls the toStream method of that
: first class with the stream as parameter. The class firstly calls the
: ::toStream of his superclass and than puts its data to the stream. On the
: receiving side you need to manufacture an empty object (of the same class)
: typically using a factory and then call the ::fromStream method of the class
: with the received stream. The class callss ::fromStream of his super class
: and then unpacks the stream in the same way. This works really well and I
:
: Andy Koch
: Koch System Engineering, Rossweid 10, CH-5619 Buettikon, Switzerland,
: Tel/Fax: +41 (0) 57 22 99 58 email: akoch@itr.ch
The only problem with the above approach is that you can't send
objects which contain const data members or references. For that,
you have to change the fromStream side to creating objects via
constructor calls. This becomes more difficult if you have cycles
in your objects.
It helps a real lot if you use a DDL to describe your data and
then generate the marshalling and unmarshalling code.
--
+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+
| Uttam M. Narsu E-mail: narsu@hks.com |
| |
| Hibbitt, Karlsson & Sorensen, Inc. Tel: (401) 727-4200 x 4442 |
| 1080 Main Street, Pawtucket RI 02860 Fax: (401) 727-4208 |
| |
| http://www.ugcs.caltech.edu/~werdna/sttng/trek6/trek6-2a2.html |
| Search for "2167" |
+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+-=+
Author: Greg Wilkins <gregw@ind.tansu.com.au>
Date: 27 Feb 1995 01:52:40 GMT Raw View
tariqh@dcs.qmw.ac.uk (Tariq Hamid) wrote:
>
> How do you marshal/unmarshal C++ objects. It appears to be a difficult problem
> as the inheritance hierarchy has to be considered.
>
There are several techniques for doing it in C++ code (with or
without the assistance of horrid macros). But all a a bit manual
and prone to some degree of error.
I think(hope) that the answer to you question is to use an external
description language to generate the base code for classes that
need to be marshal/unmarshalled (packed/unpacked, flattened/unflattened,
dump, written out/read in, etc. etc.).
Hopefully the standard for this will be IDL (CORBA), or some
extension to it for OODBs (ODMG-93).
-------------------------------------------------------------------------------
Greg Wilkins:Consultant for Object Oriented Pty. Ltd. (OOPL)|You're not Dorothy
Site @Telecom, Intelligent Network Development |I'm not Toto!
Snail:P.O. Box 1826,North Sydney,NSW.2089, Australia |And this
Email:gregw@ind.tansu.com.au (gregw@oose.com.au) |definitely is
Fax :(+61 2) 3953225 or OOPL Office:(+61 2) 9565089 |not Kansas!
Phone:(+61 2) 3953461 or OOPL Office:(+61 2) 9571092 | -Fleischman
-------------------------------------------------------------------------------
Author: smcl@sytex.com (Scott McLoughlin)
Date: Mon, 27 Feb 1995 08:38:58 GMT Raw View
Greg Wilkins <gregw@ind.tansu.com.au> writes:
> tariqh@dcs.qmw.ac.uk (Tariq Hamid) wrote:
> >
> > How do you marshal/unmarshal C++ objects. It appears to be a difficult prob
> > as the inheritance hierarchy has to be considered.
> >
>
> There are several techniques for doing it in C++ code (with or
> without the assistance of horrid macros). But all a a bit manual
> and prone to some degree of error.
>
>
Howdy,
Regarding various techniques of "marshaling" C++ objects,
do any (all?) of the techniques handle circular data structures/
object identity? If so, I'd like pointers to literature and
implementations.
=============================================
Scott McLoughlin
Conscious Computing
=============================================
Author: tariqh@dcs.qmw.ac.uk (Tariq Hamid)
Date: 22 Feb 1995 22:50:07 GMT Raw View
How do you marshal/unmarshal C++ objects. It appears to be a difficult problem
as the inheritance hierarchy has to be considered.
Thanks
Tariq.
--
Tariq Hamid | Internet: tariqh@dcs.qmw.ac.uk
32 Vivian Road | JANET: tariqh@uk.ac.qmw.dcs
Bow | Telephone\Fax: +44 81-980 1483
LONDON, E3 5RF, UK |
Author: cho11884@pax.eunet.ch (Koch Andres)
Date: Thu, 23 Feb 1995 22:59:42 GMT Raw View
Tariq Hamid (tariqh@dcs.qmw.ac.uk) wrote:
: How do you marshal/unmarshal C++ objects. It appears to be a difficult problem
: as the inheritance hierarchy has to be considered.
Not really. We used this approach in two project with message passing and
distributed processes with success. The best way (we think) is to make the
objects straemable by inheriting them from a base class which offers the
virtual interface such as CLASS::toStream and CLASS::fromStream, both take
a Stream Reference as parameter and returning the Reference too. You also
can use the operator>> or operator<< on the class, if you like.
The transporting media class gets the Object to send, and creates a stream
typically a streamable buffer, and then calls the toStream method of that
first class with the stream as parameter. The class firstly calls the
::toStream of his superclass and than puts its data to the stream. On the
receiving side you need to manufacture an empty object (of the same class)
typically using a factory and then call the ::fromStream method of the class
with the received stream. The class callss ::fromStream of his super class
and then unpacks the stream in the same way. This works really well and I
recommend that you look into the Rogue Wave tools++.h class lib, which offers
you various streams build on top of ios and a RWvistream/RWvostream which is
a virtual Stream, so that the class has not to know the format of the stream.
It also has a factory class RWFactory which is easy to use.
We also have built a Class-Lib using the RWtools++ in one project and
have built an application frame work for distributed application based
on message passing (all C++) for our projects. It serves well, especially
when interfacing with legacy systems.
Hope this gives you some path to follow.
Andy Koch
Koch System Engineering, Rossweid 10, CH-5619 Buettikon, Switzerland,
Tel/Fax: +41 (0) 57 22 99 58 email: akoch@itr.ch