changeset 119: |
85f27597cf60 |
parent: |
cae8da4b1415
|
child: |
2d1fe1d7b738 |
author: |
ellis <ellis@rwest.io> |
date: |
Fri, 22 Dec 2023 18:43:53 -0500 |
permissions: |
-rw-r--r-- |
description: |
castable added, still testing |
1 ;;; alien.lisp --- foreign alien friends 5 ;; FFI in Lisp is somewhat different than FFI in other host langs. As 6 ;; such, we usually refer to our Lispy FFI interfaces inline with the 7 ;; CMUCL terminology: alien interfaces. 9 ;; ref: https://www.sbcl.org/manual/#Foreign-Function-Interface for details 11 ;; sb-alien is a high-level interface which automatically converts C 12 ;; memory pointers to lisp objects and back, but this can be slow for 13 ;; large or complex objects. 15 ;; The lower-level interface is based on System Area Pointers (or 16 ;; SAPs), which provide untyped access to foreign memory. 18 ;; Objects which can't be automatically converted into Lisp values are 19 ;; represented by objects of type ALIEN-VALUE. 23 ;; (reexport-from :sb-vm 25 ;; '(:with-pinned-objects :with-pinned-object-iterator :with-code-pages-pinned 26 ;; :sanctify-for-execution)) 28 (defmacro define-opaque (ty &optional no-export) 30 (define-alien-type ,ty (struct ,(symbolicate ty '-t))) 31 ,(unless no-export `(export '(,ty))))) 33 (defun setfa (place from) 34 (loop for x across from 35 for i from 0 below (length from) 36 do (setf (deref place i) x))) 38 (defun copy-c-string (src dest &aux (index 0)) 39 (loop (let ((b (sb-sys:sap-ref-8 src index))) 41 (setf (fill-pointer dest) index) 43 (setf (char dest index) (code-char b)) 46 (defun clone-strings (list) 47 (with-alien ((x (* (* char)) 48 (make-alien (* char) (length list)))) 50 (labels ((populate (list index function) 52 (let ((array (sb-ext:string-to-octets (car list) :null-terminate t))) 53 (sb-sys:with-pinned-objects (array) 54 (setf (deref x index) (sap-alien (sb-sys:vector-sap array) (* char))) 55 (populate (cdr list) (1+ index) function))) 59 (loop for i below (length list) 60 do (print (cast (deref x i) c-string)))))) 63 (defmacro clone-octets-to-alien (lispa aliena) 65 `(loop for ,i from 0 below (length ,lispa) 66 do (setf (deref ,aliena ,i) 69 (defmacro clone-octets-from-alien (aliena lispa len) 71 `(loop for ,i from 0 below ,len 72 do (setf (aref ,lispa ,i) 73 (deref ,aliena ,i))))) 75 (defun foreign-int-to-integer (buffer size) 76 "Check SIZE of int BUFFER. return BUFFER." 77 (assert (= size (sb-alien:alien-size sb-alien:int :bytes))) 80 (defun foreign-int-to-bool (x size) 81 (if (zerop (foreign-int-to-integer x size)) 85 (defun bool-to-foreign-int (val) 89 (defun make-bits (length &rest args) 90 (apply #'make-array length (nconc '(:element-type bit) args))) 93 ;; (defmacro defbytes (&body bitsets) 94 ;; "For each cons-cell in BITSETS, define a new CAR-byte type for each 96 ;; `(loop for set in ',bitsets 98 ;; (let* ((ty (car set)) 101 ;; ((eq 'signed-byte ty) "I") 102 ;; ((eq 'unsigned-byte ty) "U") 103 ;; ((eq 'float ty) "F") 104 ;; (t (subseq (symbol-name ty) 0 1)))) 110 ;; `(deftype ,(symbolicate pfx (format 'nil "~a" x)) () 116 ;; (unsigned-byte 1 2 3 4 8 16 24 32 64 128) 117 ;; (signed-byte 2 3 4 8 16 24 32 64 128) 118 ;; (float 16 24 32 64 128))