[Openmcl-devel] wrapping foreign objects in lisp classes

Cyrus Harmon ch-openmcl at bobobeach.com
Mon Aug 16 16:49:53 PDT 2004


Conceptually, I like the slots approach. Here's what I cooked up to 
deal with the problem before I read about the slot-value-using-class 
stuff:

(in-package :vimage)

(defmacro def-foreign-slot (lclass lslot pslot ffield)
   `(progn
      (defmethod ,lslot ((obj ,lclass))
        (pref (,pslot obj) ,ffield))
      (defmethod ,(make-intern (strcat "set-" (symbol-name lslot))) 
((obj ,lclass) value)
        (setf (pref (,pslot obj) ,ffield) value))
      (defsetf ,lslot ,(make-intern (strcat "set-" (symbol-name lslot))))
      ))

(defclass vimage-buffer-8888 ()
   ((mac-vimage-buffer :accessor mac-vimage-buffer :initform 
(make-record :v<I>mage_<B>uffer))
    (height :reader height :writer set-height)
    (width :reader width :writer set-width)
    (rowbytes :reader rowbytes :writer set-rowbytes)
    (data :reader data :writer set-data)))

(def-foreign-slot vimage-buffer-8888 height mac-vimage-buffer 
:v<I>mage_<B>uffer.height)
(def-foreign-slot vimage-buffer-8888 width mac-vimage-buffer 
:v<I>mage_<B>uffer.width)
(def-foreign-slot vimage-buffer-8888 data mac-vimage-buffer 
:v<I>mage_<B>uffer.data)
(def-foreign-slot vimage-buffer-8888 rowbytes mac-vimage-buffer 
:v<I>mage_<B>uffer.row<B>ytes)



Not exactly the most elegant approach, but it's getting the job done 
for the moment.

Cyrus


On Aug 16, 2004, at 4:29 PM, Gary Byers wrote:

>
>
> On Mon, 16 Aug 2004, Dan Knapp wrote:
>>
>>    Using the metaobject protocol doesn't avoid having to write the
>> custom readers and
>> writers; you still need to do that.  However, you should be able to do
>> it in such a way
>> that you only need to do it once instead of for every slot of every
>> class.
>>
>
> The methods that a custom metaclass would have to override are
> SLOT-VALUE-USING-CLASS and (SETF SLOT-VALUE-USING-CLASS).  Reader and
> writer methods do the equivalent of calls to these methods in general
> (in a case where a user-defined [SETF ]SLOT-VALUE-USING-CLASS method
> could be applicable, the user-defined method will be invoked.)
>
> The Cocoa bridge implements SLOT-VALUE-USING-CLASS (and SETF thereof)
> by storing getter/setter functions (defined in terms of low-level
> memory accessors) in specialized SLOT-DEFINITION objects.
>
> In the bridge's case, it seemed natural to treat ObjC instance 
> variables
> as CLOS slots.  It may be simpler (in some ways) to simply define 
> methods
> on the fields of an encapsulated foreign structure, without trying to
> make those methods be accessor methods.  As a poor example:
>
> ;; This definition might be encoded in a .cdb file
> (def-foreign-type nil (:struct :point  ; this is a hypothetical example
>                          (:x :float)
>                          (:y :float)))
>
> (defclass point ()
>   ((real-point :initarg :real-point
>                :accessor real-point
>                :documentation "a pointer to a real point")))
>
> (defmethod point-x ((p point))
>   (let* ((real-point (real-point p)))
>     (pref real-point :point.x)))
>
>
> (defmethod (setf point-x) (new (p point))
>   (let* ((real-point (real-point p)))
>     (setf (pref real-point :point.x) new)))
>
>
> You might want these methods to do a little more type- and 
> sanity-checking
> than is shown here, but it seems like most/all of that is boilerplate:
> given a foreign structure definition, it's probably not too hard to
> generate an encapsulating class and methods to access that structure's
> fields.
>
> (You wouldn't have the ability to use SLOT-VALUE or WITH-SLOTS on the
> foreign field, but you'd be able to deal with a foreign structure and
> its fields at a fairly high level.)
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel




More information about the Openmcl-devel mailing list