3.3. Foreign objects

While the foreign function invocation protocols differ strongly between platforms and implementations, foreign objects are pretty easy to handle portably. For ECL, a foreign object is just a bunch of bytes stored in memory. The lisp object for a foreign object encapsulates several bits of information:

A foreign object may contain many different kinds of data: integers, floating point numbers, C structures, unions, etc. The actual type of the object is stored in a list or a symbol which is understood by the higher level interface (Section 3.4).

The most important component of the object is the memory region where data is stored. By default ECL assumes that the user will perform automatic managment of this memory, deleting the object when it is no longer needed. The first reason is that this block may have been allocated by a foreign routine using malloc(), or mmap(), or statically, by referring to a C constant. The second reason is that foreign functions may store references to this memory which ECL is not aware of and, in order to keep these references valid, ECL should not attempt to automatically destroy the object.

In many cases, however, it is desirable to automatically destroy foreign objects once they have been used. The higher level interfaces UFFI and CFFI provide tools for doing this. For instance, in the following example adapted from the UFFI documentation, the string NAME is automatically deallocated

(def-function "gethostname" 
  ((name (* :unsigned-char))
   (len :int))
  :returning :int)

(if (zerop (c-gethostname (uffi:char-array-to-pointer name) 256))
    (format t "Hostname: ~S" (ffi:convert-from-foreign-string name))
    (error "gethostname() failed."))