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.| +----------------------+---------------------------------------------+