I would like to be able to generate alien arrays whose length is determined
at run time, but I am having trouble understanding how to do this using
(sb-alien:with-alien () ) or make-alien.
My attempt at this, along the lines shown below, fails:
> This is SBCL 1.0.2, an implementation of ANSI Common Lisp.
> More information about SBCL is available at <http://www.sbcl.org/>.
> SBCL is free software, provided as is, with absolutely no warranty.
...
> CL-USER> (defun my-func (a-seq)
> (sb-alien:with-alien
> ((x (array (sb-alien:unsigned 32) (length a-seq)))) x))
>
>; in: LAMBDA NIL
>; (WITH-ALIEN ((X (ARRAY (UNSIGNED 32) (LENGTH A-SEQ)))) X)
>;
>; caught ERROR:
>; (in macroexpansion of (WITH-ALIEN # X))
>; (hint: For more precise location, try *BREAK-ON-SIGNALS*.)
>; The first dimension is not a non-negative fixnum or NIL: (LENGTH A-SEQ)
>; (SB-INT:NAMED-LAMBDA MY-FUNC (A-SEQ) (BLOCK MY-FUNC (WITH-ALIEN ((X
#)) X)))
>; ==>
>; #'(SB-INT:NAMED-LAMBDA MY-FUNC (A-SEQ) (BLOCK MY-FUNC (WITH-ALIEN ((X
#)) X)))
>;
>; caught STYLE-WARNING:
>; The variable A-SEQ is defined but never used.
>;
>; compilation unit finished
>; caught 1 ERROR condition
>; caught 1 STYLE-WARNING condition
...
I find I can only use a literal fixnum, not a symbol or form that evaluates
to a fixnum, in the dimension specification for the array x.
A second attempt (which also includes a simple test):
> (defun my-func (a-seq)
> (eval
> `(sb-alien:with-alien
> ((x (array (sb-alien:unsigned 32) ,(length a-seq))))
> (loop for k below ,(length a-seq) do
> (setf (sb-alien:deref x k) (elt ,a-seq k))
> (format t "~d:~d~%" k (sb-alien:deref x k))))))
>MY-FUNC
>CL-USER> (my-func #(1 2 3 4 5 4 3 2 1))
>0:1
>1:2
>2:3
>3:4
>4:5
>5:4
>6:3
>7:2
>8:1
>NIL
>
appears to work, but seems awkward to me - as though I am missing
something. Is there a more straightforward way to go about this?
The point of converting to an alien array is for passing data to a linux
kernel module. At the moment I am using a solution (not shown) that simply
hard-wires the array size to the maximum possible for the application, and
this works, but I am hoping for something more efficient.
In case it matters, I am using sbcl 1.02 on
Linux 2.6.17-1.2174_FC5 #1 Tue Aug 8 15:30:55 EDT 2006 i686 i686 i386
GNU/Linux
Regards,
Mark
|