Navigation:  Programming Cookbook > External Interfacing > External Libraries >

Returning Structures

Previous pageReturn to chapter overviewNext page

Dolphin's external call primitives allow structures to be returned by reference or by value. Normally such structures will be subclasses of ExternalStructure (or if not, they must have the same form). For example:

makeRect: left top: top right: right bottom: bottom

  "    RECT MakeRect(LONG left, LONG top, LONG right, LONG bottom)

      {

          return RECT(left, top, right, bottom);

      }

  Calling this function and having the external function call primitive instantiate and

  return a RECT is also considerably faster than building it in Smalltalk!"

  <stdcall: RECT AnswerDQWORD sdword sdword sdword sdword>

  ^self invalidCall

 

This method of VMLibrary makes a sneaky use of the external call primitive argument/return value conversion in order to rapidly instantiate a Win32™ RECT structure from four-byte integers.

The VM's ability to instantiate external structures is very useful (particularly for implementing COM interfaces where structures are quite frequently passed in as arguments), and often means that no further manual conversion of the return value (or call-in argument) is needed; however because the structure is directly instantiated by the VM, it may not be properly initialized.

Where one's class includes any specific initialization (e.g. an #initialize method), or has a custom implementation of #new, then one may need to send some appropriate messages to the VM instantiated object. This is not normally an issue because ExternalStructures mostly just represent external structures without adding significant extra state and behaviour. In some unusual cases, however, one may prefer to instantiate the correct object oneself, and this can be done by simply specifying the return value as an untyped pointer (lpvoid) or untyped structure (<N>, where N is the byte size of the structure). The resulting ExternalAddress or ByteArray can be used to construct the appropriate Smalltalk object. In either case, it is desirable to write a wrapper method to perform the necessary custom operations.

The above also applies to structure parameters to callback (i.e. call-in) methods or blocks.