changeset 222: |
83e823b80219 |
parent: |
17c05cd3e549
|
child: |
fdea20982c25 |
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Sun, 03 Mar 2024 20:50:37 -0500 |
permissions: |
-rw-r--r-- |
description: |
add os module |
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 (shadowing-import '(sb-unix::syscall sb-unix::syscall* sb-unix::int-syscall sb-unix::with-restarted-syscall sb-unix::void-syscall) :std) 25 ;; (reexport-from :sb-vm 27 ;; '(:with-pinned-objects :with-pinned-object-iterator :with-code-pages-pinned 28 ;; :sanctify-for-execution)) 30 (defun shared-object-name (name) 31 "Return a filename with the correct extension for a shared library 33 #+darwin (format nil "/usr/local/lib/lib~a.dylib" name) 34 #-darwin (format nil "lib~a.so" name)) 36 (defun list-all-shared-objects () 37 sb-alien::*shared-objects*) 39 (defmacro define-alien-loader (name &optional export) 40 "Define a default loader function named load-NAME which calls 41 SB-ALIEN:LOAD-SHARED-OBJECT." 42 (let* ((fname (sb-int:symbolicate (format nil "~@:(load-~a~)" name)))) 44 (defun ,fname (&optional save) 45 (prog1 (sb-alien:load-shared-object (shared-object-name ',name) :dont-save (not save)) 46 (pushnew ,(sb-int:keywordicate (string-upcase name)) *features*))) 47 ,@(when export (list `(export '(,fname))))))) 49 (defmacro define-opaque (ty &optional no-export) 51 (define-alien-type ,ty (struct ,(symbolicate ty '-t))) 52 ,(unless no-export `(export '(,ty))))) 54 (defun setfa (place from) 55 (loop for x across from 56 for i from 0 below (length from) 57 do (setf (deref place i) x))) 59 (defun copy-c-string (src dest &aux (index 0)) 60 (loop (let ((b (sb-sys:sap-ref-8 src index))) 62 (setf (fill-pointer dest) index) 64 (setf (char dest index) (code-char b)) 67 (defun clone-strings (list) 68 (with-alien ((x (* (* char)) 69 (make-alien (* char) (length list)))) 71 (labels ((populate (list index function) 73 (let ((array (sb-ext:string-to-octets (car list) :null-terminate t))) 74 (sb-sys:with-pinned-objects (array) 75 (setf (deref x index) (sap-alien (sb-sys:vector-sap array) (* char))) 76 (populate (cdr list) (1+ index) function))) 80 (loop for i below (length list) 81 do (print (cast (deref x i) c-string)))))) 84 (defun c-strings-to-string-list (c-strings) 85 (declare (type (alien (* c-string)) c-strings)) 86 (let ((reversed-result nil)) 87 (dotimes (i most-positive-fixnum) 88 (declare (type index i)) 89 (let ((c-string (deref c-strings i))) 91 (push c-string reversed-result) 92 (return (nreverse reversed-result))))))) 94 (defmacro clone-octets-to-alien (lispa aliena) 96 `(loop for ,i from 0 below (length ,lispa) 97 do (setf (deref ,aliena ,i) 100 (defmacro clone-octets-from-alien (aliena lispa len) 102 `(loop for ,i from 0 below ,len 103 do (setf (aref ,lispa ,i) 104 (deref ,aliena ,i))))) 106 (defun foreign-int-to-integer (buffer size) 107 "Check SIZE of int BUFFER. return BUFFER." 108 (assert (= size (sb-alien:alien-size sb-alien:int :bytes))) 111 (defun foreign-int-to-bool (x size) 112 (if (zerop (foreign-int-to-integer x size)) 116 (defun bool-to-foreign-int (val)