arrays in CMUCL
Helmut Eller <e9626484-jqqTQQGuSV4hHGrKhHam0bNldLUNz+W/@public.gmane.org> Fri, 16 Aug 2002 16:59:50 +0200
| Newsgroups | gmane.lisp.uffi.general |
|---|---|
| Message-ID | <[email protected]> |
Hi,
I would like to write a binding for the pipe system call. So, I
defined:
(def-function ("pipe" c/pipe)
((fds (:array :int 2)))
:returning :int)
And a wrapper like this:
(defun pipe ()
(with-foreign-object (fds '(:array :int 2))
(let ((status (c/pipe fds)))
(ecase status
(-1 (signal-posix-error))
(0 (values (deref-array fds '(:array :int) 0)
(deref-array fds '(:array :int) 1)))))))
This works nice in Allegro, but in CMUCL I only get results like:
* (pipe)
#<Alien (array (alien:signed 32) 2) at #xBFFFF53C>
#<Alien (array (alien:signed 32) 2) at #xBFFFF544>
I investigated the WITH-FOREIGN-OBJECT macro a bit. Apparently, the
problem stems from the conversion of the array to a pointer with
ALIEN:ADDR. As a workaround, I modified WITH-FOREIGN-OBJECT so that
only non-array objects are converted to pointers:
(in-package :uffi)
(defmacro with-foreign-object ((var type) &rest body)
#-(or cmu lispworks) ; default version
`(let ((,var (allocate-foreign-object ,type)))
(unwind-protect
(progn ,@body)
(free-foreign-object ,var)))
#+cmu
(let ((obj (gensym))
(type (eval type)))
`(alien:with-alien ((,obj ,(convert-from-uffi-type type :allocate)))
(let ((,var ,(if (and (consp type)
(eq :array (car type)))
obj
`(alien:addr ,obj))))
,@body)))
#+lispworks
`(fli:with-dynamic-foreign-objects ((,var ,(convert-from-uffi-type
(eval type) :allocate)))
,@body)
)
Is there a better way to do this?
Regards,
Helmut