Re: Coercing pointers

Edi Weitz <[email protected]> 12 Aug 2003 17:20:41 +0200
Newsgroups gmane.lisp.uffi.general
Message-ID <[email protected]>
On Tue, 12 Aug 2003 08:22:53 -0600, Kevin Rosenberg <kevin-HJRc7zDS/[email protected]> wrote:

> You can try editing deref-array in aggregates.lisp to use the type
> field for cmucl and lispworks. Currently, that field is only used
> for Allegro which requires the type information since pointers are
> represented by integers with Allegro.
> 
> It appears that Lispworks, at least, can use fli:dereference to
> coerce from one pointer type to another.

OK, below is a patch.

With that patch my code now looks like this (which seems more natural
to me):

  (def-function ("gdImagePngPtr" gd-image-png-ptr)
      ((im gd-image-ptr)
       (size (* :int)))
    :returning :pointer-void
    :module "gd")

  (defun png-to-stream (stream image)
    (cond ((subtypep (stream-element-type stream) 'character)
            (with-foreign-object (size :int)
              (with-foreign-object (memory :char)
                (setq memory (gd-image-png-ptr image size))
                (dotimes (i (deref-pointer size :int))
                  (write-char (ensure-char-character (deref-array memory :char i))
                              stream)))))
          ((subtypep (stream-element-type stream) '(unsigned-byte 8))
            (with-foreign-object (size :int)
              (with-foreign-object (memory :unsigned-byte)
                (setq memory (gd-image-png-ptr image size))
                (dotimes (i (deref-pointer size :int))
                  (write-byte (deref-array memory :unsigned-byte i)
                              stream)))))
          (t (error "Can't use a stream with element-type ~A"
                    (stream-element-type stream)))))

I've tested this with CMUCL 18e and LW 4.2.7 pro on Linux. I've left
the #+(or cmu scl) stuff as is but I don't have SCL to test it.

However, this only works with CMUCL if I also make the change to
primitives.lisp (see below) which sets :CHAR in CMUCL to mean
(ALIEN:UNSIGNED 8). Is there a specific reason for (ALIEN:SIGNED 8)?

Cheers,
Edi.


  edi@bird:/usr/local/lisp/source/uffi/src > diff -u aggregates.lisp.orig aggregates.lisp
  --- aggregates.lisp.orig        Tue Aug 12 17:09:02 2003
  +++ aggregates.lisp     Tue Aug 12 16:40:26 2003
  @@ -158,11 +159,11 @@

   (defmacro deref-array (obj type i)
     "Returns a field from a row"
  -  #+(or lispworks cmu sbcl scl) (declare (ignore type))
  -  #+(or cmu scl)  `(alien:deref ,obj ,i)
  +  #+sbcl (declare (ignore type))
  +  #+(or cmu scl)  `(alien:deref (alien:cast ,obj (* ,(convert-from-uffi-type type :type))) ,i)
     #+sbcl  `(sb-alien:deref ,obj ,i)
  -  #+lispworks `(fli:dereference ,obj :index ,i)
     #+allegro `(ff:fslot-value-typed (quote ,(convert-from-uffi-type type :type)) :c ,obj ,i)
  +  #+lispworks `(fli:dereference ,obj :type (quote ,(convert-from-uffi-type type :type)) :index ,i)
     #+mcl
     (let* ((array-type (array-type type))
            (local-type (convert-from-uffi-type array-type :allocation))
  edi@bird:/usr/local/lisp/source/uffi/src > diff -u objects.lisp.orig objects.lisp
  --- objects.lisp.orig   Tue Aug 12 17:09:16 2003
  +++ objects.lisp        Tue Aug 12 16:40:58 2003
  @@ -103,10 +103,10 @@

   (defmacro deref-pointer (ptr type)
     "Returns a object pointed"
  -  #+(or cmu sbcl lispworks scl) (declare (ignore type))
  -  #+(or cmu scl)  `(alien:deref ,ptr)
  +  #+sbcl (declare (ignore type))
  +  #+(or cmu scl)  `(alien:deref (alien:cast ,ptr (* ,(convert-from-uffi-type type :type))))
     #+sbcl  `(sb-alien:deref ,ptr)
  -  #+lispworks `(fli:dereference ,ptr)
  +  #+lispworks `(fli:dereference ,ptr :type (quote ,(convert-from-uffi-type type :type)))
     #+allegro `(ff:fslot-value-typed (quote ,(convert-from-uffi-type type :deref)) :c ,ptr)
     #+mcl `(ccl:pref ,ptr ,(convert-from-uffi-type type :deref))
     )
  edi@bird:/usr/local/lisp/source/uffi/src > diff -u primitives.lisp.orig primitives.lisp
  --- primitives.lisp.orig        Tue Aug 12 17:09:27 2003
  +++ primitives.lisp     Tue Aug 12 17:08:08 2003
  @@ -91,7 +91,7 @@

   #+(or cmu scl)
   (defparameter *cmu-sbcl-def-type-list*
  -    '((:char . (alien:signed 8))
  +    '((:char . (alien:unsigned 8))
         (:unsigned-char . (alien:unsigned 8))
         (:byte . (alien:signed 8))
         (:unsigned-byte . (alien:unsigned 8))