Re: with-foreign-object wrapper, extra indirection & need of CMUCL's ADDR operator
Kevin Rosenberg <kevin-HJRc7zDS/[email protected]> Fri, 22 Mar 2002 14:02:57 -0700 (MST)
| Newsgroups | gmane.lisp.uffi.general |
|---|---|
| Message-ID | <[email protected]> |
> Whereas with MAKE-ALIEN made dynamic objects, ADDR is not suitable since
> we already have a pointer to the memory.
Jorg, this is the code for with-foreign-object:
(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)))
`(alien:with-alien ((,obj ,(convert-from-uffi-type type :allocate)))
(let ((,var (alien:addr ,obj)))
,@body)))
#+lispworks
`(fli:with-dynamic-foreign-objects ((,var ,(convert-from-uffi-type
type :allocate)))
,@body)
)
By using the addr function, I get a pointer to memory which makes the var
consistent with what I'd get if I used make-alien.
> I hope that appropriate use of MACROLET or symbol-macros for the names
> defined via WITH-* (e.g. NAME) can help solve these issues.
Interesting thought. I haven't used symbol-macros. I hope that using the
addr function will substitute for this technique. If not, I can
investigate this further.
> > This indirection consistent is the other implementations.
> I don't understand the grammar of the last sentence?
Sorry. In general, the other implementations (as well as make-alien)
return a pointer to the allocated object rather than CMUCL's with-alien
which binds the object itself.
> 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.
I believe that you are right about LW. ACL can provide this to, however, I
choose to have have ACL return a bignum (without typing of course) that
points to the allocated memory. The slot/pointer/array dereferencing
functions receives the type information from the UFFI call to accesses the
object. I chose this technique, rather than using ACL's typed objects,
since the compiler can open-code the access to the object given its type
information in the access function.
Since the type information is already passed to the access function in ACL
(ff:fslot-value-typed), ACL is happy with using a memory address. I wonder
if it is possible to do something like this for CLISP. This may be easier
than creating a "foreign types". So, the CLISP foreign-allocate can return
a bignum for the memory address. The work then has to go into the access
functions to convert the object at the memory address to the proper lisp
object given the type passed to the access function.
> 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.
Yes, that's right!
Kevin