Accessing object variables at runtime

Hi

I'm searching for a way to access the types of even the private variables of
an object at runtime.

Maybe a bit off topic, but I think that this group knows best about RTTI and
those things.

Why I need it:
When you have many objects on your heap that points to each other (I don't
know the english word for the datastructure, but in german it's called a
'web'), you run into problems when streaming all this objects.

Say, you have the following objects:

type
  anObject = class
    private
      First,
      Second : anObject;
  end;

var
  a,b,c : anObject;

a.First := b;
a.Second := c;
b.First := c;
b.Second := c;
c.First := a;
b.Second := a;

Of course, you can't store the pointer values, you have to transform them to
another kind of ID.
One approach I know is to traverse all known pointers and change them. But
if you have something like a circle (First: a -> b -> c) you'll have to
notify this and handle accordingly.

Several months ago, I needed a structure where I could store all my objects
(btw: non-visual, for a syntactical analysis). So I build a TList-Descendant
that I called 'ObjectSpace', that holds OSObjects. All my data-objects are
derived from this OSObject. When you create a descendant, the Create-method
registers your object in the object-space by assigning a counter-value. If
you free your object, it gets deregistered. (When you forget forget to free,
the ObjectSpace can give you a warning - quite nice for long-running
programs ;+) The ObjectSpace has methods SaveToStream and LoadFromStream,
which calls the according methods for all objects it contains.

Here begins my problem: The counter-value (unique in each ObjectSpace) is
perfect for replacing the pointer values, but I have to know which variables
in the descendants are also derived from OSObject, and therefore, where
counter-values have to be resolved to addresses (after reloading from a
stream).

hmm, I'm not sure, if this is clear, so I'll give an example:

a has the counter-value 1
b ... 2
c ... 3

a has to override the SaveToStream method and has to store '2' instead of
the address of 'First' -- b stores '3' and c stores '1' (the counter-value
is defined as protected in OSObject). In LoadFromStream they read the
integer-values, which need to be resolved to the (new and therefore
different) addresses of the objects they stand for. Since the mapping
OSObject-descendant -> counter-value will be the same after loading, the
OSObject 'knows' the new address for each counter-value.

But -- how does the ObjectSpace know, which address in memory is an
OSObject-descendant?!?

'Till now, my solution is to require the implementation of a method
'ResolveOSHandleToObject' (abstract), where the descendant (who knows him
better!:>) has to call an OSObject-method 'ObjectFromHandle', where he gets
the new address for a particular counter-value ( = OSHandle, btw.).

I would prefer a solution where the ObjectSpace handles all the resolving,
but it would have to know what to resolve. I think that it must be possible
(see the Code-Explorer or the De{*word*81}), but I found only a way to get this
information (descendent of a particular class) for published or public
variables.

I need it for privates, too!

thank you (at least, for reading so far ;+)

Jan