Navigation: Programming Cookbook > External Interfacing >
External Memory Management
On occasion it is necessary to take responsibility for managing the lifetime of objects allocated externally. Such external resources are not, by default, automatically managed by the Dolphin garbage collector, and explicit freeing is required. However, managing the lifetime of such objects can automatically initiated by the garbage collector if we make use of Weak Collections and Finalization.
Usually external memory blocks (e.g. containing externally allocated structures) are referenced via instances of ExternalAddress.
ExternalAddress is marked as a class of "indirection" objects, which means that the VM's external call primitives will treat it differently to normal byte objects when used as an argument to an external method, depending on the parameter type. For example, when passed to lpvoid parameters, the contents of the ExternalAddress, as opposed to its own address, will be passed, i.e. the ExternalAddress is automatically dereferenced. See Parameter Types, Validation and Conversion for further details.
Integers (small and 4-byte large) are also treated as indirection objects, and so can often be used interchangeably with ExternalAddresses. SmallIntegers are not, however, mutable and cannot be passed to lppvoid parameter types.
The address of the contents of byte-object can be retried by sending it the #yourAddress message. The answer will be an Integer, usually small, which can be converted to an ExternalAddress by sending it the #asExternalAddress message.
External memory blocks that are known to have been allocated from the standard Win32 process heap are best referenced via instances of the ExternalAddress subclass ExternalMemory, which uses finalization to automatically free the memory block back to the heap when the Smalltalk object is garbage collected. An ExternalStructure can be created on a memory block referenced via an ExternalMemory instance by sending the appropriate subclass the #fromAddress: instantiator with the ExternalMemory as the argument.
One can construct an empty ExternalStructure sub-instance ready to point at an externally allocated block (which will presumably be filled in by some external function call) by sending the message #newHeapPointer to the appropriate ExternalStructure subclass.
Certain add-in packages (such as OLE COM) add ExternalMemory subclasses for managing external memory blocks from heaps other than the default process heap (e.g. COMTaskMemory), and one can easily add your own subclasses if required.
The various subclasses of ExternalMemory implement a class side protocol for allocating and freeing dynamic memory from various external heaps. In fact they all implement the COM interface, IMalloc, which is an object-oriented abstract for a heap.
ExternalHandle is a special class of object used to represent opaque 32-bit handles to external objects and structures. These are sometimes pointers to objects or structures with a private format, and sometimes some other form of integer handle from which allocator of the handle can uniquely identify a particular resource. ExternalHandles should always be used to refer to external resources which are only valid for the lifetime of a running image, but which will no longer be valid on image restart. As of Dolphin 4.0, ExternalHandles are automatically set to null (zero) by the VM at image load time. This removes the need to add special start-up handling to do the same in the image, speeding start-up and making it more reliable.