A foreign type which passes the address of a Lisp array direct to C.
keyword
:lisp-array &optional type
type⇩ |
A list. The default is nil . |
The FLI type :lisp-array
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, or allocated pinnable and pinned using with-pinned-objects.
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.
Windows version:
__declspec(dllexport) void __cdecl ProcessFloats(int count, float * fvec, double * dvec) { for(--count ; count >= 0 ; count--) { dvec[count] = fvec[count] * fvec[count]; } }
Non-Windows version:
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)))))
Now:
(test-process-floats 3)
prints:
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
:lisp-simple-1d-array
with-dynamic-lisp-array-pointer
with-pinned-objects
Foreign Language Interface User Guide and Reference Manual - 01 Dec 2021 19:34:59