Coercing pointers
Edi Weitz <[email protected]> 12 Aug 2003 15:01:51 +0200
| Newsgroups | gmane.lisp.uffi.general |
|---|---|
| Message-ID | <[email protected]> |
Hi!
I'm trying to use the GD library <http://www.boutell.com/gd/> with
CMUCL and LW and part of my UFFI code looks like this:
(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 '(:array :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 '(:array :unsigned-byte) i) stream)))))
(t (error "Can't use a stream with element-type ~A"
(stream-element-type stream)))))
I had hopes that this would work but at least LW seems to have
problems if the return type of GD-IMAGE-PNG-PTR is declared to be
:POINTER-VOID. I get messages like
Error: Attempted to dereference a pointer to aggregate type :VOID.
Now, I can change the DEF-FUNCTION above and replace :POINTER-VOID
with (* CHAR) or (* (UNSIGNED-BYTE 8)) but in both cases one of the
DEREF-ARRAYs above won't work. To be more specific, if
GD-IMAGE-PNG-PTR is declared to return (* CHAR), then DEREF-ARRAY will
return a character in both COND cases, i.e. the second (type) argument
to DEREF-ARRAY is completely ignored. And vice versa.
Am I doing something wrong or isn't it possible to coerce a
:POINTER-VOID to something else in UFFI? But if that's so what's the
point of having this type?
It is possible to do what I want at least with LW and CMUCL as the
kludgy code below shows:
(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 #+lispworks
(fli:dereference memory :index i :type :char)
#+cmu
(code-char (alien:deref (alien:cast memory (* (alien:unsigned 8))) 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 #+lispworks
(fli:dereference memory :index i :type '(:unsigned :byte))
#+cmu
(alien:deref (alien:cast memory (* (alien:unsigned 8))) i)
stream)))))
(t (error "Can't use a stream with element-type ~A"
(stream-element-type stream)))))
Thanks,
Edi.