Hi all,
I've updated the cffi-new-translators branch, improving the exported interface and fixing a few bugs. The branch is available via Darcs (or a browser to browse the source) at:
http://slacknet.com/~jamesjb/cffi-new-translators
The exported interface for defining type translators is by specializing the following generic functions:
Generic Function: TRANSLATE-TO-FOREIGN value type-name
Convert the Lisp object VALUE to a foreign object of the type named by TYPE-NAME, which is a symbol naming a type defined by DEFCTYPE. Methods on this generic function should EQL-specialize TYPE-NAME for the type to translate.
Returns the translated foreign object and an optional second value that will be passed as the PARAM argument to FREE-TRANSLATED-OBJECT.
Generic Function: TRANSLATE-FROM-FOREIGN value type-name
Convert the foreign object VALUE of the type named by TYPE-NAME, which is a symbol naming a type defined by DEFCTYPE, to a Lisp object. Methods on this generic function should EQL-specialize TYPE-NAME for the type to translate.
Generic Function: FREE-TRANSLATED-OBJECT value type-name param
Perform necessary deallocation of the foreign object VALUE, of the type named by TYPE-NAME, which is a symbol naming a type defined by DEFCTYPE. Methods on this generic function should EQL-specialize TYPE-NAME for the type to deallocate.
PARAM will contain the second value returned by TRANSLATE-TO-FOREIGN for this type, or NIL if no second value was present.
If no deallocation is required, it is not necessary to specialize this method.
Here's an example, a simplified version of the :boolean type:
(defctype boolean :int)
(defmethod translate-to-foreign (value (type (eql 'boolean))) (if value 1 0))
(defmethod translate-from-foreign (value (type (eql 'boolean))) (not (zerop value)))
Also, look at examples/gettimeofday.lisp and translator-test.lisp for more examples.
There is another, unexported, set of generic functions used internally for translating whole classes of types. Look at TRANSLATE-TYPE-{TO,FROM}-FOREIGN and FREE-TYPE-TRANSLATED-OBJECT for these (and methods defined on them for FOREIGN-ENUM, etc).
With respect to the old :TO-C-DYNAMIC translators, I'm inclined to not worry about optimizing this case until there is a specific performance need for it. I think the ability to dispatch on the type of the value being translated is more useful than the optimization it was providing.
Comments?
James