Loading arrays.lisp +19 −17 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ (in-package :hello-c) (in-package :ffx) (defparameter *gl-rsrc* nil) Loading @@ -46,7 +46,7 @@ (progn (loop for fgn in *fgn-mem* do (print fgn) (fgn-free (fgn-ptr fgn)) (foreign-free (fgn-ptr fgn)) finally (setf *fgn-mem* nil)) (loop for fgn in *gl-rsrc* do (print fgn) Loading @@ -72,11 +72,11 @@ (let ((amt (gensym)) (ptr (gensym))) `(let* ((,amt ,amt-form) (,ptr (allocate-foreign-object ,type ,amt))) (,ptr (falloc ,type ,amt))) (call-fgn-alloc ,type ,amt ,ptr (list ,@keys))))) (defun call-fgn-alloc (type amt ptr keys) ;;(print `(fgnalloc ,type ,amt ,keys)) ;;(print `(call-fgn-alloc ,type ,amt ,keys)) (fgn-ptr (car (push (make-fgn :id keys :type type :amt amt Loading @@ -84,12 +84,14 @@ *fgn-mem*)))) (defun fgn-free (&rest fgn-ptrs) (loop for fgn-ptr in fgn-ptrs do ;; (print `(fgn-free freeing ,@fgn-ptrs)) (let ((start (copy-list fgn-ptrs))) (loop for fgn-ptr in start do (let ((fgn (find fgn-ptr *fgn-mem* :key 'fgn-ptr))) (if fgn (setf *fgn-mem* (delete fgn *fgn-mem*)) (format t "~&Freeing unknown FGN ~a" fgn-ptr)) (free-foreign-object fgn-ptr)))) (foreign-free fgn-ptr))))) (defun gllog (type resource amt &rest keys) (push (make-fgn :id keys Loading Loading @@ -138,7 +140,7 @@ (defun ff-floatv-setf (array &rest floats) (loop for f in floats and n upfrom 0 do (setf (deref-array array '(:array :float) n) (* 1.0 f))) do (setf (mem-aref array :float n) (* 1.0 f))) array) ;--------- with-ff-array-elements ------------------------------------------ Loading @@ -147,17 +149,17 @@ (defmacro with-ff-array-elements ((fa type &rest refs) &body body) `(let ,(let ((refn -1)) (mapcar (lambda (ref) `(,ref (deref-array ,fa '(:array ,type) ,(incf refn)))) `(,ref (mem-aref ,fa ,type) ,(incf refn))) refs)) ,@body)) ;-------- ff-elt --------------------------------------- (defmacro ff-elt-p (v n) `(deref-array ,v '(:array (* :void)) ,n)) `(mem-aref ,v :pointer ,n)) (defmacro ff-elt (v type n) `(deref-array ,v '(:array ,type) ,n)) `(mem-aref ,v ',type ,n)) (defun elti (v n) (ff-elt v :int n)) Loading @@ -172,10 +174,10 @@ (setf (ff-elt v :float n) (coerce value 'float))) (defun elt$ (v n) (ff-elt v :cstring n)) (ff-elt v :string n)) (defun (setf elt$) (value v n) (setf (ff-elt v :cstring n) value)) (setf (ff-elt v :string n) value)) (defun eltd (v n) (ff-elt v :double n)) Loading @@ -184,7 +186,7 @@ (setf (ff-elt v :double n) (coerce value 'double-float))) (defmacro fgn-pa (pa n) `(deref-array ,pa '(:array (* :void)) ,n)) `(mem-aref ,pa :pointer ,n)) (eval-when (compile load eval) (export '(ffx-reset Loading callbacks.lisp +16 −26 Original line number Diff line number Diff line Loading @@ -21,8 +21,10 @@ ;;; IN THE SOFTWARE. (in-package :hello-c) (in-package :ffx) #+precffi (defun ff-register-callable (callback-name) #+allegro (ff:register-foreign-callable callback-name) Loading @@ -33,8 +35,18 @@ (print (list :ff-register-callable-returns cb)) cb)) (defun ff-register-callable (callback-name) (let ((known-callback (cffi:get-callback callback-name))) (assert known-callback) known-callback)) (defmacro ff-defun-callable (call-convention result-type name args &body body) (declare (ignorable call-convention)) `(defcallback ,name ,result-type ,args ,@body)) #+precffi (defmacro ff-defun-callable (call-convention result-type name args &body body) (declare (ignorable result-type)) (declare (ignorable call-convention result-type)) (let ((native-args (when args ;; without this p-f-a returns '(:void) as if for declare (process-function-args args)))) #+lispworks Loading @@ -50,35 +62,13 @@ ,@body))) #+test (ff-defun-callable :cdecl :int square ((arg-1 :int)(data (* :void))) #+(or) (ff-defun-callable :cdecl :int square ((arg-1 :int)(data :pointer)) (list data (* arg-1 arg-1))) (defmacro ff-def-call ((module iname ename) args) #+cormanlisp (assert module () "Module (dll name, in fact) required for Corman Lisp") #+cormanlisp `(ct:defun-dll ,iname ,args :return-type :short :library-name ,module ;; required according Corman doc :entry-name ,ename :linkage-type :c) ;; ?? #+allegro (declare (ignorable module)) #+allegro `(ff:def-foreign-call (,iname ,ename) ,args) #+lispworks `(fli:define-foreign-function (,iname ,ename) ,(mapcar (lambda (arg) (if (listp (cadr arg)) (list (car arg) (substitute :pointer '* (cadr arg))) arg)) args) :module ,module :result-type :int)) (eval-when (compile load eval) (export '(ff-register-callable ff-defun-callable ff-def-call ff-pointer-address))) No newline at end of file definers.lisp +50 −5 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ ;; $Header: /project/cello/cvsroot/hello-c/definers.lisp,v 1.1 2005/05/23 23:51:57 ktilton Exp $ (in-package :hello-c) (in-package :ffx) (eval-when (compile load eval) (export '( Loading @@ -46,11 +46,56 @@ ;;; (fli:make-pointer :address n :pointer-type '(:pointer :void))) (defun make-ff-pointer (n) #+allegro (ff:make-foreign-pointer :address n :type '(* void)) #+lispworks (fli:make-pointer :address n :pointer-type '(:pointer :void)) #-(or lispworks allegro) n #+clisp (ffi:unsigned-foreign-address n) #-(or clisp lispworks) n ) (defmacro defun-ffx (rtn module$ name$ (&rest type-args) &body post-processing) (declare (ignore module$)) (let* ((lisp-fn (lisp-fn name$)) (lispfn (intern (string-upcase name$))) (var-types (let (args) (assert (evenp (length type-args)) () "uneven arg-list for ~a" name$) (dotimes (n (floor (length type-args) 2) (nreverse args)) (let ((type (elt type-args (* 2 n))) (var (elt type-args (1+ (* 2 n))))) (when (eql #\* (elt (symbol-name var) 0)) ;; no, good with *: (setf var (intern (subseq (symbol-name var) 1))) (setf type :pointer)) (push (list var type) args))))) (cast-vars (mapcar (lambda (var-type) (copy-symbol (car var-type))) var-types))) `(progn (cffi:defcfun (,name$ ,lispfn) ,(if (and (consp rtn) (eq '* (car rtn))) :pointer rtn) ,@var-types) (defun ,lisp-fn ,(mapcar #'car var-types) (let ,(mapcar (lambda (cast-var var-type) `(,cast-var ,(if (listp (cadr var-type)) (car var-type) (case (cadr var-type) (:int `(coerce ,(car var-type) 'integer)) (:long `(coerce ,(car var-type) 'integer)) (:unsigned-long `(coerce ,(car var-type) 'integer)) (:unsigned-int `(coerce ,(car var-type) 'integer)) (:float `(coerce ,(car var-type) 'float)) (:double `(coerce ,(car var-type) 'double-float)) (:string (car var-type)) (:pointer (car var-type)) (otherwise (let ((ffc (get (cadr var-type) 'ffi-cast))) (assert ffc () "Don't know how to cast ~a" (cadr var-type)) `(coerce ,(car var-type) ',ffc))))))) cast-vars var-types) (prog1 (,lispfn ,@cast-vars) ,@post-processing))) (eval-when (compile eval load) (export '(,lispfn ,lisp-fn)))))) #+precffi (defmacro defun-ffx (rtn module$ name$ (&rest type-args) &body post-processing) (let* ((lisp-fn (lisp-fn name$)) (lispfn (intern (string-upcase name$))) Loading Loading @@ -81,7 +126,7 @@ (:unsigned-int `(coerce ,(car var-type) 'integer)) (:float `(coerce ,(car var-type) 'float)) (:double `(coerce ,(car var-type) 'double-float)) (:cstring (car var-type)) (:string (car var-type)) (otherwise (let ((ffc (get (cadr var-type) 'ffi-cast))) (assert ffc () "Don't know how to cast ~a" (cadr var-type)) Loading Loading @@ -121,7 +166,7 @@ (defmacro dft (ctype ffi-type ffi-cast) `(progn (setf (get ',ctype 'ffi-cast) ',ffi-cast) (def-foreign-type ,ctype ,ffi-type) (defctype ,ctype ,ffi-type) (eval-when (compile eval load) (export ',ctype)))) Loading ffi-extender.lisp 0 → 100644 +51 −0 Original line number Diff line number Diff line (in-package :cl-user) (defpackage #:ffi-extender (:nicknames #:ffx) (:shadowing-import-from #:cffi #:with-foreign-object #:load-foreign-library #:with-foreign-string) (:use #:common-lisp #:cffi) (:export #:def-type #:def-foreign-type #:def-constant #:null-char-p #:def-enum #:def-struct #:get-slot-value #:get-slot-pointer #:def-array-pointer #:def-union #:allocate-foreign-object #:with-foreign-object #:with-foreign-objects #:size-of-foreign-type #:pointer-address #:deref-pointer #:ensure-char-character #:ensure-char-integer #:ensure-char-storable #:null-pointer-p #:+null-cstring-pointer+ #:char-array-to-pointer #:with-cast-pointer #:def-foreign-var #:convert-from-cstring #:convert-to-cstring #:free-cstring #:with-cstring #:with-cstrings #:def-function #:find-foreign-library #:load-foreign-library #:default-foreign-library-type #:run-shell-command #:convert-from-foreign-string #:convert-to-foreign-string #:allocate-foreign-string #:with-foreign-string #:foreign-string-length ; not implemented #:convert-from-foreign-usb8 )) (in-package :ffx) No newline at end of file hello-cffi.asd 0 → 100644 +24 −0 Original line number Diff line number Diff line ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;(declaim (optimize (debug 2) (speed 1) (safety 1) (compilation-speed 1))) (declaim (optimize (debug 3) (speed 3) (safety 1) (compilation-speed 0))) #-(or openmcl sbcl cmu clisp lispworks ecl allegro cormanlisp) (error "Sorry, this Lisp is not yet supported. Patches welcome!") (asdf:defsystem :hello-cffi :name "Hello CFFI" :author "Kenny Tilton <ktilton@nyc.rr.com>" :version "1.0.0" :maintainer "Kenny Tilton <ktilton@nyc.rr.com>" :licence "Lisp Lesser GNU Public License" :description "CFFI Add-ons" :long-description "Extensions and utilities for CFFI" :depends-on (:cffi :cffi-uffi-compat) :serial t :components ((:file "my-uffi-compat") (:file "ffi-extender") (:file "definers") (:file "arrays") (:file "callbacks"))) Loading
arrays.lisp +19 −17 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ (in-package :hello-c) (in-package :ffx) (defparameter *gl-rsrc* nil) Loading @@ -46,7 +46,7 @@ (progn (loop for fgn in *fgn-mem* do (print fgn) (fgn-free (fgn-ptr fgn)) (foreign-free (fgn-ptr fgn)) finally (setf *fgn-mem* nil)) (loop for fgn in *gl-rsrc* do (print fgn) Loading @@ -72,11 +72,11 @@ (let ((amt (gensym)) (ptr (gensym))) `(let* ((,amt ,amt-form) (,ptr (allocate-foreign-object ,type ,amt))) (,ptr (falloc ,type ,amt))) (call-fgn-alloc ,type ,amt ,ptr (list ,@keys))))) (defun call-fgn-alloc (type amt ptr keys) ;;(print `(fgnalloc ,type ,amt ,keys)) ;;(print `(call-fgn-alloc ,type ,amt ,keys)) (fgn-ptr (car (push (make-fgn :id keys :type type :amt amt Loading @@ -84,12 +84,14 @@ *fgn-mem*)))) (defun fgn-free (&rest fgn-ptrs) (loop for fgn-ptr in fgn-ptrs do ;; (print `(fgn-free freeing ,@fgn-ptrs)) (let ((start (copy-list fgn-ptrs))) (loop for fgn-ptr in start do (let ((fgn (find fgn-ptr *fgn-mem* :key 'fgn-ptr))) (if fgn (setf *fgn-mem* (delete fgn *fgn-mem*)) (format t "~&Freeing unknown FGN ~a" fgn-ptr)) (free-foreign-object fgn-ptr)))) (foreign-free fgn-ptr))))) (defun gllog (type resource amt &rest keys) (push (make-fgn :id keys Loading Loading @@ -138,7 +140,7 @@ (defun ff-floatv-setf (array &rest floats) (loop for f in floats and n upfrom 0 do (setf (deref-array array '(:array :float) n) (* 1.0 f))) do (setf (mem-aref array :float n) (* 1.0 f))) array) ;--------- with-ff-array-elements ------------------------------------------ Loading @@ -147,17 +149,17 @@ (defmacro with-ff-array-elements ((fa type &rest refs) &body body) `(let ,(let ((refn -1)) (mapcar (lambda (ref) `(,ref (deref-array ,fa '(:array ,type) ,(incf refn)))) `(,ref (mem-aref ,fa ,type) ,(incf refn))) refs)) ,@body)) ;-------- ff-elt --------------------------------------- (defmacro ff-elt-p (v n) `(deref-array ,v '(:array (* :void)) ,n)) `(mem-aref ,v :pointer ,n)) (defmacro ff-elt (v type n) `(deref-array ,v '(:array ,type) ,n)) `(mem-aref ,v ',type ,n)) (defun elti (v n) (ff-elt v :int n)) Loading @@ -172,10 +174,10 @@ (setf (ff-elt v :float n) (coerce value 'float))) (defun elt$ (v n) (ff-elt v :cstring n)) (ff-elt v :string n)) (defun (setf elt$) (value v n) (setf (ff-elt v :cstring n) value)) (setf (ff-elt v :string n) value)) (defun eltd (v n) (ff-elt v :double n)) Loading @@ -184,7 +186,7 @@ (setf (ff-elt v :double n) (coerce value 'double-float))) (defmacro fgn-pa (pa n) `(deref-array ,pa '(:array (* :void)) ,n)) `(mem-aref ,pa :pointer ,n)) (eval-when (compile load eval) (export '(ffx-reset Loading
callbacks.lisp +16 −26 Original line number Diff line number Diff line Loading @@ -21,8 +21,10 @@ ;;; IN THE SOFTWARE. (in-package :hello-c) (in-package :ffx) #+precffi (defun ff-register-callable (callback-name) #+allegro (ff:register-foreign-callable callback-name) Loading @@ -33,8 +35,18 @@ (print (list :ff-register-callable-returns cb)) cb)) (defun ff-register-callable (callback-name) (let ((known-callback (cffi:get-callback callback-name))) (assert known-callback) known-callback)) (defmacro ff-defun-callable (call-convention result-type name args &body body) (declare (ignorable call-convention)) `(defcallback ,name ,result-type ,args ,@body)) #+precffi (defmacro ff-defun-callable (call-convention result-type name args &body body) (declare (ignorable result-type)) (declare (ignorable call-convention result-type)) (let ((native-args (when args ;; without this p-f-a returns '(:void) as if for declare (process-function-args args)))) #+lispworks Loading @@ -50,35 +62,13 @@ ,@body))) #+test (ff-defun-callable :cdecl :int square ((arg-1 :int)(data (* :void))) #+(or) (ff-defun-callable :cdecl :int square ((arg-1 :int)(data :pointer)) (list data (* arg-1 arg-1))) (defmacro ff-def-call ((module iname ename) args) #+cormanlisp (assert module () "Module (dll name, in fact) required for Corman Lisp") #+cormanlisp `(ct:defun-dll ,iname ,args :return-type :short :library-name ,module ;; required according Corman doc :entry-name ,ename :linkage-type :c) ;; ?? #+allegro (declare (ignorable module)) #+allegro `(ff:def-foreign-call (,iname ,ename) ,args) #+lispworks `(fli:define-foreign-function (,iname ,ename) ,(mapcar (lambda (arg) (if (listp (cadr arg)) (list (car arg) (substitute :pointer '* (cadr arg))) arg)) args) :module ,module :result-type :int)) (eval-when (compile load eval) (export '(ff-register-callable ff-defun-callable ff-def-call ff-pointer-address))) No newline at end of file
definers.lisp +50 −5 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ ;; $Header: /project/cello/cvsroot/hello-c/definers.lisp,v 1.1 2005/05/23 23:51:57 ktilton Exp $ (in-package :hello-c) (in-package :ffx) (eval-when (compile load eval) (export '( Loading @@ -46,11 +46,56 @@ ;;; (fli:make-pointer :address n :pointer-type '(:pointer :void))) (defun make-ff-pointer (n) #+allegro (ff:make-foreign-pointer :address n :type '(* void)) #+lispworks (fli:make-pointer :address n :pointer-type '(:pointer :void)) #-(or lispworks allegro) n #+clisp (ffi:unsigned-foreign-address n) #-(or clisp lispworks) n ) (defmacro defun-ffx (rtn module$ name$ (&rest type-args) &body post-processing) (declare (ignore module$)) (let* ((lisp-fn (lisp-fn name$)) (lispfn (intern (string-upcase name$))) (var-types (let (args) (assert (evenp (length type-args)) () "uneven arg-list for ~a" name$) (dotimes (n (floor (length type-args) 2) (nreverse args)) (let ((type (elt type-args (* 2 n))) (var (elt type-args (1+ (* 2 n))))) (when (eql #\* (elt (symbol-name var) 0)) ;; no, good with *: (setf var (intern (subseq (symbol-name var) 1))) (setf type :pointer)) (push (list var type) args))))) (cast-vars (mapcar (lambda (var-type) (copy-symbol (car var-type))) var-types))) `(progn (cffi:defcfun (,name$ ,lispfn) ,(if (and (consp rtn) (eq '* (car rtn))) :pointer rtn) ,@var-types) (defun ,lisp-fn ,(mapcar #'car var-types) (let ,(mapcar (lambda (cast-var var-type) `(,cast-var ,(if (listp (cadr var-type)) (car var-type) (case (cadr var-type) (:int `(coerce ,(car var-type) 'integer)) (:long `(coerce ,(car var-type) 'integer)) (:unsigned-long `(coerce ,(car var-type) 'integer)) (:unsigned-int `(coerce ,(car var-type) 'integer)) (:float `(coerce ,(car var-type) 'float)) (:double `(coerce ,(car var-type) 'double-float)) (:string (car var-type)) (:pointer (car var-type)) (otherwise (let ((ffc (get (cadr var-type) 'ffi-cast))) (assert ffc () "Don't know how to cast ~a" (cadr var-type)) `(coerce ,(car var-type) ',ffc))))))) cast-vars var-types) (prog1 (,lispfn ,@cast-vars) ,@post-processing))) (eval-when (compile eval load) (export '(,lispfn ,lisp-fn)))))) #+precffi (defmacro defun-ffx (rtn module$ name$ (&rest type-args) &body post-processing) (let* ((lisp-fn (lisp-fn name$)) (lispfn (intern (string-upcase name$))) Loading Loading @@ -81,7 +126,7 @@ (:unsigned-int `(coerce ,(car var-type) 'integer)) (:float `(coerce ,(car var-type) 'float)) (:double `(coerce ,(car var-type) 'double-float)) (:cstring (car var-type)) (:string (car var-type)) (otherwise (let ((ffc (get (cadr var-type) 'ffi-cast))) (assert ffc () "Don't know how to cast ~a" (cadr var-type)) Loading Loading @@ -121,7 +166,7 @@ (defmacro dft (ctype ffi-type ffi-cast) `(progn (setf (get ',ctype 'ffi-cast) ',ffi-cast) (def-foreign-type ,ctype ,ffi-type) (defctype ,ctype ,ffi-type) (eval-when (compile eval load) (export ',ctype)))) Loading
ffi-extender.lisp 0 → 100644 +51 −0 Original line number Diff line number Diff line (in-package :cl-user) (defpackage #:ffi-extender (:nicknames #:ffx) (:shadowing-import-from #:cffi #:with-foreign-object #:load-foreign-library #:with-foreign-string) (:use #:common-lisp #:cffi) (:export #:def-type #:def-foreign-type #:def-constant #:null-char-p #:def-enum #:def-struct #:get-slot-value #:get-slot-pointer #:def-array-pointer #:def-union #:allocate-foreign-object #:with-foreign-object #:with-foreign-objects #:size-of-foreign-type #:pointer-address #:deref-pointer #:ensure-char-character #:ensure-char-integer #:ensure-char-storable #:null-pointer-p #:+null-cstring-pointer+ #:char-array-to-pointer #:with-cast-pointer #:def-foreign-var #:convert-from-cstring #:convert-to-cstring #:free-cstring #:with-cstring #:with-cstrings #:def-function #:find-foreign-library #:load-foreign-library #:default-foreign-library-type #:run-shell-command #:convert-from-foreign-string #:convert-to-foreign-string #:allocate-foreign-string #:with-foreign-string #:foreign-string-length ; not implemented #:convert-from-foreign-usb8 )) (in-package :ffx) No newline at end of file
hello-cffi.asd 0 → 100644 +24 −0 Original line number Diff line number Diff line ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;(declaim (optimize (debug 2) (speed 1) (safety 1) (compilation-speed 1))) (declaim (optimize (debug 3) (speed 3) (safety 1) (compilation-speed 0))) #-(or openmcl sbcl cmu clisp lispworks ecl allegro cormanlisp) (error "Sorry, this Lisp is not yet supported. Patches welcome!") (asdf:defsystem :hello-cffi :name "Hello CFFI" :author "Kenny Tilton <ktilton@nyc.rr.com>" :version "1.0.0" :maintainer "Kenny Tilton <ktilton@nyc.rr.com>" :licence "Lisp Lesser GNU Public License" :description "CFFI Add-ons" :long-description "Extensions and utilities for CFFI" :depends-on (:cffi :cffi-uffi-compat) :serial t :components ((:file "my-uffi-compat") (:file "ffi-extender") (:file "definers") (:file "arrays") (:file "callbacks")))