[comp.lang.c++] I/O problem

niklas@appli.se (Niklas Hallqvist) (11/03/90)

	Hello out there...

	Is there a way to do portable binary I/O on classes with virtual
functions?  Yes, I know there is, by letting the objects them self provide
a binary image via a virtual function.  But what I want is to write some-
thing like:

class A { private: int x; public: virtual int y(void) { return x; }};
void put(A* a) { write(1, &a, sizeof(a)); }
A* get(void) { A* a = new A; read(0, &a, sizeof(a)); return a; }

And what happens here?  Aha, the vtbl pointer gets saved along with the
binary image, and will be read in by other programs using the get function.
No harm in that, is it?  Well, YES!!!!  Another program would be differently
laid out in memory and the vtbl ptr would not be valid there.  Unpredictable
results will follow the first virtual call.  Now don't tell me you can't
do something like this without rewriting all the classes one want to be
able to store this way.  Summary: How would you do if you had a "black box"-
class (i.e no source, just relocatable object code) and wanted to do I/O,
keeping the objects full state (even private info)?

					Thanks, Niklas

-- 
Niklas Hallqvist	Phone: +46-(0)31-40 75 00
Applitron Datasystem	Fax:   +46-(0)31-83 39 50
Molndalsvagen 95	Email: niklas@appli.se
S-412 63  GOTEBORG, Sweden     mcsun!sunic!chalmers!appli!niklas

dlw@odi.com (Dan Weinreb) (11/05/90)

In article <1179@appli.se> niklas@appli.se (Niklas Hallqvist) writes:

   And what happens here?  Aha, the vtbl pointer gets saved along with the
   binary image, and will be read in by other programs using the get function.
   No harm in that, is it?  Well, YES!!!!  Another program would be differently
   laid out in memory and the vtbl ptr would not be valid there.  Unpredictable
   results will follow the first virtual call. 

Notice that there's an even worse problem if any of your classes
contain pointer-valued data members.

jimad@microsoft.UUCP (Jim ADCOCK) (11/07/90)

In article <1179@appli.se> niklas@appli.se (Niklas Hallqvist) writes:
|	Is there a way to do portable binary I/O on classes with virtual
|functions?  Yes, I know there is, by letting the objects them self provide
|a binary image via a virtual function.  But what I want is to write some-
|thing like:
|
|class A { private: int x; public: virtual int y(void) { return x; }};
|void put(A* a) { write(1, &a, sizeof(a)); }
|A* get(void) { A* a = new A; read(0, &a, sizeof(a)); return a; }
|
|And what happens here?  Aha, the vtbl pointer gets saved along with the
|binary image, and will be read in by other programs using the get function.
|No harm in that, is it?  Well, YES!!!!  Another program would be differently
|laid out in memory and the vtbl ptr would not be valid there.  Unpredictable
|results will follow the first virtual call.  Now don't tell me you can't
|do something like this without rewriting all the classes one want to be
|able to store this way.  

The vtable pointer would seem to be just a special case of a general problem --
pointers in general.  If you are going to store out objects into a file, then
read them back in later at a different address, possibly even into a different
program, then you're going to have to do something special to have any pointers
in the objects make sense after they are reconstituted.  This problem is 
typically handled by creating some kind of persistent object identifiers for
objects on disk, swizzle internal representation pointers to these persistent
IDs before writing to a disk, and deswizzle the pointers when the objects are
read back in at new locations.  Vtable pointers, Vbase pointers, and other
nasty bits have to be handled as special cases of this general technique.
For example, vtable pointers might be swizzled to a persistent type identifier.

|Summary: How would you do if you had a "black box"-
|class (i.e no source, just relocatable object code) and wanted to do I/O,
|keeping the objects full state (even private info)?

My claim would be that without source nor "debugger" info you can't,
since you cannot with certainty determine what are the pointers needing to
be swizzled to PIDs.  This is equivalent to the the problem with conservative
garbage collectors -- Since pointers are never identified with certainty, 
objects cannot be moved.

rmartin@clear.com (Bob Martin) (11/09/90)

>In article <1179@appli.se> niklas@appli.se (Niklas Hallqvist) writes:
>|	Is there a way to do portable binary I/O on classes with virtual
>|functions? 

Are you aware of the Object Oriented Data Base Management Systems
(OODBMS) that are on the Market?  These packages do what you are
asking about, including the swizzling of the pointers.  They
are very very slick!

Check into Object Design, Versant, and Ontologic.  These companies
produce OODBMSs for C++.
									
-- 
+-Robert C. Martin-----+---------------------------------------------+
| rmartin@clear.com    | My opinions are mine.  They aren't anybody  |
| uunet!clrcom!rmartin | elses.  And thats the way I want to keep it.|
+----------------------+---------------------------------------------+