Article # 32, added by Geoworks, historical record
| first | previous | index | next | last |

How to use the ObjDoRelocation() and ObjDoUnRelocation() functions to relocate and unrelocate resources.




Quoting from the description for the ObjDoUnRelocation function in the
Routines book: "This routine unrelocates a given word or dword. It
translates a handle, a segment address, or an entry point back into a
resource ID. The translation done is the exact reverse of that done by
ObjDoRelocation(). See that routine (above) for more information."

So what exactly does that mean? I think of this as taking a handle or optr
to a resource and turning it into a special kind of identifier. This
identifier is simply a resource "type" combined with an index. This
information is used later for recreating a handle or optr by calling
ObjDoRelocation. The handle or optr created may not be the same value it
was before, but it will refer to the same resource as before. 

This mechanism is used whenever the system is saving objects or blocks to
a file. The system will take the optr or handle of the resource,
unrelocate it, and save it. Later when the system wants to load the
resource from the file it will "relocate" the resource ID back into an
optr or handle. 

If we didn't unrelocate the optr or handle, we'd have a problem later on
when the resource is read into memory from the file. The handle that we
saved earlier may now be in use by another program, and thus we cannot use
it. So rather than cause conflicts between resources, we unrelocate the
optr or handle, save it, then later relocate it into a new optr or handle.
This new optr or handle is pointing to our resource we're reading in from
disk, and can be used without worry of conflict. 

For an example of where you might use these two functions, consider you
have an object. This object is saved to a VM file. Within this object you
have instance data, say an optr to a chunk array, which is also saved in
the VM file. This optr is valid when you first use the object and chunk
array. However, when you later reopen the VM file and read the object and
chunk array back into memory, the optr stored in the object may not be
valid anymore. You will have to first unrelocate the optr before saving
the object to file. Then when you open the file later, relocate the "optr"
(which is really a resource ID) back into a valid optr. Here is an
example: 

    MemHandle mh;

    mh = OptrToHandle( pself->MOI_chunk );
    ObjDoUnRelocation( RELOC_RELOC_HANDLE,
                       OptrToHandle( oself ),
                       (Handle*)&mh,
                       (word*)&mh );
    pself->MOI_chunk = ConstructOptr( mh, OptrToChunk( MOI_chunk ) );
    Mark object dirty, so it will be saved by VM manager.
    Save object to file.

    ... (program exits, later relaunches)...

    Object is read from file.
    mh = OptrToHandle( pself->MOI_chunk );
    ObjDoRelocation( RELOC_RELOC_HANDLE,
                     OptrToHandle( oself ),
                     (word*)&mh,
                     (Handle*)&mh );
    pself->MOI_chunk = ConstructOptr( mh, OptrToChunk( MOI_chunk ) );

We use OptrToHandle( oself ) for the second parameter because that is the
handle of the block containing the relocation. In other words, the object
block. ObjDo[Un]Relocation uses this for optimization purposes when
relocating something within the same block as the object. 

For relocating optrs to objects, see the article "Relocating Objects".