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 <
> SBCL is free software, provided as is, with absolutely no warranty.
> CL-USER> (defun my-func (a-seq)
> ((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)
> ((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))))))
>CL-USER> (my-func #(1 2 3 4 5 4 3 2 1))
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