X-Git-Url: https://git.distorted.org.uk/~mdw/clg/blobdiff_plain/9adccb27da69b60d058aa37867d55ea20ecf97ca..3840beb25c5aefcb3b8b1d101b50d6f8dd90b6f0:/glib/ffi.lisp?ds=sidebyside diff --git a/glib/ffi.lisp b/glib/ffi.lisp index 0391858..7580646 100644 --- a/glib/ffi.lisp +++ b/glib/ffi.lisp @@ -15,28 +15,10 @@ ;; License along with this library; if not, write to the Free Software ;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -;; $Id: ffi.lisp,v 1.2 2004-11-06 21:39:58 espen Exp $ +;; $Id: ffi.lisp,v 1.4 2004-11-09 10:04:35 espen Exp $ (in-package "GLIB") -;;;; - -;; Sizes of fundamental C types in bytes (8 bits) -(defconstant +size-of-short+ 2) -(defconstant +size-of-int+ 4) -(defconstant +size-of-long+ 4) -(defconstant +size-of-pointer+ 4) -(defconstant +size-of-float+ 4) -(defconstant +size-of-double+ 8) - -;; Sizes of fundamental C types in bits -(defconstant +bits-of-byte+ 8) -(defconstant +bits-of-short+ 16) -(defconstant +bits-of-int+ 32) -(defconstant +bits-of-long+ 32) - - - ;;;; Foreign function call interface @@ -108,11 +90,11 @@ (push doc/arg docs) (progn (destructuring-bind (expr type &optional (style :in)) doc/arg - (unless (member style '(:in :out :in-out)) + (unless (member style '(:in :out :in-out :return)) (error "Bogus argument style ~S in ~S." style doc/arg)) (when (and (not supplied-lambda-list) - (namep expr) (member style '(:in :in-out))) + (namep expr) (member style '(:in :in-out :return))) (push expr lambda-list)) (push (list (if (namep expr) @@ -127,30 +109,36 @@ #+cmu (defun %defbinding (foreign-name lisp-name lambda-list return-type docs args) (ext:collect ((alien-types) (alien-bindings) (alien-parameters) - (alien-values) (cleanup-forms)) + (return-values) (cleanup-forms)) (dolist (arg args) (destructuring-bind (var expr type style) arg (let ((declaration (alien-type type)) (cleanup (cleanup-form var type))) (cond - ((member style '(:out :in-out)) - (alien-types `(* ,declaration)) - (alien-parameters `(addr ,var)) - (alien-bindings - `(,var ,declaration - ,@(when (eq style :in-out) - (list (to-alien-form expr type))))) - (alien-values (from-alien-form var type))) - (cleanup - (alien-types declaration) - (alien-bindings - `(,var ,declaration ,(to-alien-form expr type))) - (alien-parameters var) - (cleanup-forms cleanup)) - (t - (alien-types declaration) - (alien-parameters (to-alien-form expr type))))))) + ((member style '(:out :in-out)) + (alien-types `(* ,declaration)) + (alien-parameters `(addr ,var)) + (alien-bindings + `(,var ,declaration + ,@(when (eq style :in-out) + (list (to-alien-form expr type))))) + (return-values (from-alien-form var type))) + ((eq style :return) + (alien-types declaration) + (alien-bindings + `(,var ,declaration ,(to-alien-form expr type))) + (alien-parameters var) + (return-values (from-alien-form var type))) + (cleanup + (alien-types declaration) + (alien-bindings + `(,var ,declaration ,(to-alien-form expr type))) + (alien-parameters var) + (cleanup-forms cleanup)) + (t + (alien-types declaration) + (alien-parameters (to-alien-form expr type))))))) (let* ((alien-name (make-symbol (string lisp-name))) (alien-funcall `(alien-funcall ,alien-name ,@(alien-parameters)))) @@ -168,12 +156,12 @@ (unwind-protect ,(from-alien-form alien-funcall return-type) ,@(cleanup-forms)) - ,@(alien-values)) + ,@(return-values)) `(progn (unwind-protect ,alien-funcall ,@(cleanup-forms)) - (values ,@(alien-values))))))))) + (values ,@(return-values))))))))) ;;; Creates bindings at runtime @@ -197,7 +185,23 @@ (apply #'alien:alien-funcall alien args)) (mapc #'funcall cleanup-arguments args))))) - + +(defmacro defcallback (name (return-type &rest args) &body body) + `(def-callback ,name + (,(alien-type return-type) + ,@(mapcar #'(lambda (arg) + (destructuring-bind (name type) arg + `(,name ,(alien-type type)))) + args)) + ,(to-alien-form + `(let (,@(mapcar #'(lambda (arg) + (destructuring-bind (name type) arg + `(,name ,(from-alien-form name type)))) + args)) + ,@body) + return-type))) + + ;;;; Definitons and translations of fundamental types @@ -235,6 +239,21 @@ (def-type-method destroy-function ()) +;; Sizes of fundamental C types in bytes (8 bits) +(defconstant +size-of-short+ 2) +(defconstant +size-of-int+ 4) +(defconstant +size-of-long+ 4) +(defconstant +size-of-pointer+ 4) +(defconstant +size-of-float+ 4) +(defconstant +size-of-double+ 8) + +;; Sizes of fundamental C types in bits +(defconstant +bits-of-byte+ 8) +(defconstant +bits-of-short+ 16) +(defconstant +bits-of-int+ 32) +(defconstant +bits-of-long+ 32) + + (deftype int () '(signed-byte #.+bits-of-int+)) (deftype unsigned-int () '(unsigned-byte #.+bits-of-int+)) (deftype long () '(signed-byte #.+bits-of-long+)) @@ -394,7 +413,7 @@ (defmethod writer-function ((type (eql 'single-float)) &rest args) (declare (ignore type args)) #'(lambda (value location &optional (offset 0)) - (setf (sap-ref-single location offset) (coerce value 'single-float))))) + (setf (sap-ref-single location offset) (coerce value 'single-float)))) (defmethod reader-function ((type (eql 'single-float)) &rest args) (declare (ignore type args)) @@ -482,6 +501,7 @@ (deallocate-memory string)))) (defmethod cleanup-function ((type (eql 'string)) &rest args) + (declare (ignore args)) #'(lambda (string) (unless (null-pointer-p string) (deallocate-memory string))))