:lisp-array
is a foreign type which accepts a Lisp array and passes a pointer to the first element of that array. The Lisp array may be non-simple.
It is vital that the garbage collector does not move the Lisp array, hence
:lisp-array
checks that the array is statically allocated.
Note also that the Lisp garbage collector does not know about the array in the C code. Therefore, if the C function retains a pointer to the array, then you must ensure the Lisp object is not collected, for example by retaining a pointer to it in Lisp.
The argument
type
, if non-nil, is a list
(
element-type
&rest
dimensions
)
and is used to check the element type and dimensions of the Lisp array passed.
This C function fills an array of doubles from an array of single floats.
__declspec(dllexport) void __cdecl ProcessFloats(int count, float * fvec, double * dvec)
{
for(--count ; count >= 0 ; count--) {
dvec[count] = fvec[count] * fvec[count];
}
}
void ProcessFloats(int count, float * fvec, double * dvec)
{
for(--count ; count >= 0 ; count--) {
dvec[count] = fvec[count] * fvec[count];
}
}
The following Lisp code demonstrates the use of
:lisp-array
in a call to
ProcessFloats
:
(fli:define-foreign-function (process-floats
"ProcessFloats")
((count :int)
(fvec :lisp-array)
(dvec :lisp-array)))
(defun test-process-floats (length)
(let ((f-vector
(make-array length
:element-type 'single-float
:initial-contents
(loop for x below
length
collect
(coerce x 'single-float))
:allocation :static))
(d-vector
(make-array length
:element-type 'double-float
:initial-element 0.0D0
:allocation :static)))
(process-floats length f-vector d-vector)
(dotimes (x length)
(format t "f-vector[~D] = ~A; d-vector[~D] = ~A~%"
x (aref f-vector x)
x (aref d-vector x)))))
(test-process-floats 3)
single-array[0] = 0.0; double-array[0] = 0.0
single-array[1] = 1.0; double-array[1] = 1.0
single-array[2] = 2.0; double-array[2] = 4.0