with-foreign-object wrapper, extra indirection & need of CMUCL's ADDR operator
"Hoehle, Joerg-Cyril" <[email protected]> Fri, 22 Mar 2002 13:17:15 +0100
| Newsgroups | gmane.lisp.uffi.general |
|---|---|
| Message-ID | <[email protected]> |
Hi,
First, I believe a WITH- form for (hopefully) stack allocation is a good thing to have (useful level of abstraction and flexibility).
> (defun gethostname2 ()
> "Returns the hostname"
> (uffi:with-foreign-object (name (:array :unsigned-char 256))
> (if (zerop (c-gethostname (uffi:char-array-to-pointer name) 256))
> (uffi:convert-from-foreign-string name)
> (error "gethostname() failed."))))
> doing this for CMUCL is that objects are quite a bit different when
> allocated with make-alien vs. with-alien. There is basically an extra
> level of indirection with make-alien.
To be explicit about CMUCL for people who don't know (please ignore typos):
(with-alien ((name (array (unsigned 8) 256)))
(alien-funcall
(extern-alien "gethostname"
(function integer (* (array (unsigned 8) 256)) integer))
(ADDR name) 256)) ; pointer to array is passed
^^^^ unlike C, where & of an array is implicit
Whereas with MAKE-ALIEN made dynamic objects, ADDR is not suitable since we already have a pointer to the memory.
I hope that appropriate use of MACROLET or symbol-macros for the names defined via WITH-* (e.g. NAME) can help solve these issues.
> This indirection consistent is
> the other implementations.
I don't understand the grammar of the last sentence?
> At this point, I'm not sure how cleanly I can
> use CMUCL stack allocation and still keep pointer references
> consistent
> with make-alien objects and with objects in other implementations.
If I understand you right, I believe the exact same problem would occur with the extension to CLISP that I'm currently thinking about: adding alloc+free!
(FOREIGN-ALLOC (ARRAY uint8 256) &optional init)
yields a foreign variable object. A foreign variable is a typed pointer (a tuple of an address and a foreign type), I believe similar to what LispWorks provides.
This Lisp object embodies an indirection, since its address part is a reference to the actual array bytes.
So a foreign function that uses this array would of course have to be declared as (name (* (array uint8 256))).
^^
Voila, the extra level of indirection I believe you talk about.
Regards,
Jorg Hohle.