Navigation:  Programming Cookbook > External Interfacing > External Structures >

ExternalStructure

Previous pageReturn to chapter overviewNext page

All of the data types intended for interfacing with the outside world from Dolphin are subclasses of ExternalStructure, This applies to scalar, usually 32-bit, values, as well as "structures". The contents of an ExternalStructure are represented with an object that understands the external bytes protocol (e.g. ByteArray and ExternalAddress). The external bytes protocol includes a number of primitive operations for accessing the native machine representations of fundamental types such as signed and unsigned 32-bit integers, and double precision floats, at specified offsets. For example, given an 8 byte ByteArray, if one sends it #dwordAtOffset: with the argument 4, then it would answer the 32-bit unsigned integer value stored from offset 4 to offset 7 inclusive.

The external bytes protocol has primitive accessors for 32-bit signed and unsigned integers, 16-bit signed and unsigned integers, unsigned bytes, 64-bit floating point numbers, 32-bit floating pointer numbers, strings, etc. Using these primitive accessors it is possible to hand code a structure class that provides higher-level accessors for each field. However this is a very tedious and error prone process, because it involves a lot of typing, and one has to work out the correct field offsets by hand. In addition one has to code a method for each field to which access is required, even when one would rather not have all those methods clanking around in the image.

Structure Templates

In order to largely automate the process of defining external structures, every ExternalStructure subclass can have a template defined that specifies symbolic names and type descriptors for each field in the corresponding structure. The template definition is stored in the #defineTemplate class method. A simple example is POINTL (the Dolphin structure to represent the Windows™ POINTL structure):

defineFields

  "Define the fields of the Win32 POINTL structure.

      POINTL compileDefinition

  "

  self

      defineField: #x type: SDWORDField new;

      defineField: #y type: SDWORDField new

 

Here we've said that Windows™ POINTLs contain a pair of signed 32-bit integer coordinates, which they do!

Having defined structure, we can then start to use it immediately by using the field names defined in the template as message selectors (e.g. to get the x coordinate of a POINTL we would simply send it #x, and to set it, #x:). The ExternalStructure infrastructure will take care of lazily initializing the template so that it knows the layout and size of the structure. We can also embed structures inside other structures without worrying about the initialization order. However, unless we compile the structure definition explicitly, then we will not get optimum performance since the fields will be accessed dynamically.

Structures can be compiled for optimum performance by sending them the #compileDefinition method, and this will automatically generate a set of correctly defined accessor methods (assuming that one has managed to code the #defineTemplate method correctly, which is most easily achieved by following the countless examples in the base image). Compiled structures do occupy more space in the image, so infrequently used structures are best left uncompiled.

If we hadn't required read and/or write access to all the fields of POINTL, then we could have restricted the access available to specific fields to read only, write only, or no access (filler).