confused about types and pointers
rif <[email protected]> Tue, 11 May 2004 17:37:56 -0400
| Newsgroups | gmane.lisp.uffi.general |
|---|---|
| Message-ID | <[email protected]> |
Sorry if this question is too tedious or too long or too vague. I've
been banging on this for a few days, and I'm fairly confused. As
mentioned, I've been trying to write a UFFI wrapper (or a CMUCL
wrapper) for the R programming language. At this point, I have a 40
line C "proof of concept" that works, and 200 lines of Lisp that don't
succeed at doing the same thing.
There is a rather complicated structure called a sexprec, and a
pointer to a sexprec is a sexp. I have the following function that's
used to tell R to allocate:
(def-function ("Rf_allocVector" +rf-alloc-vector+)
((s sexptype)
(n :int))
:returning sexp)
For example, I could tell R to give me an object in which to
pass/store an integer by saying
RCLG> (setf *a* (+rf-alloc-vector+ sexptype#intsxp 1))
#<Alien (*
<---complicated structure omitted--->
at #x08D5A210>
It gets tricky, because to actually store an element in the structure,
you don't use it as the structure itself, but you treat it as a
different kind of structure (what a mess). In C, you'd write:
INTEGER_DATA(robj)[0] = 3;
which C macroexpands (successively) into
(INTEGER(robj))[0] = 3;
((int *) DATAPTR(robj))[0] = 3;
((int *) (((SEXPREC_ALIGN *) (robj)) + 1) [0] = 3;
(Note that robj is a C sexp here.)
In Lisp, I have the following functions to create/read back integers
in robj's:
(defun int-to-robj (n)
"Returns an R object corresponding to an integer."
(let ((robj (+rf-alloc-vector+ sexptype#intsxp 1))))
(with-cast-pointer (robj robj 'sexprec-align) ;; alias robj
(let ((data (deref-array robj '(:array sexprec-align) 1)))
(with-cast-pointer (data data :int)
(setf (deref-pointer data :int) n))))
robj))
(defun robj-to-int (robj)
"Returns the integer inside an R object. Assumes it's an
integral robj."
(with-cast-pointer (robj robj 'sexprec-align)
(let ((data (deref-array robj '(:array sexprec-align) 1)))
(with-cast-pointer (data data :int)
(deref-pointer data :int)))))
These seem to work in tests, but I don't know if they're right, or if
they only seem to work "by accident" because they're both making the
same mistake in the same way. Should there be another derefence
somewhere?
Any thoughts are appreciated, as I'm starting to feel hopeless. Some
more specific questions:
Question 1. One thing I don't understand (that maybe will help build
my mental model) is why, when I call deref-pointer on *a*, the address
does not change. The * disappears in the above description, as I
expect, (so it's just the structure, no longer a pointer to the
structure), but the address does not change. I'd expect the deref'd
pointer to actually point to a different location in memory from the
original.
Question 2. (Clearly related to 1 in a way I don't quite grasp.)
Should I need to do a deref-pointer before setting slot-values on the
underlying sexprec structure?
Cheers,
rif