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