1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10; Package: UFFI -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
6 ;;;; Purpose: UFFI source to handle objects and pointers
7 ;;;; Programmers: Kevin M. Rosenberg and John DeSoi
8 ;;;; Date Started: Feb 2002
10 ;;;; $Id: objects.cl,v 1.2 2002/09/20 04:51:14 kevin Exp $
12 ;;;; This file, part of UFFI, is Copyright (c) 2002 by Kevin M. Rosenberg
15 ;;;; UFFI users are granted the rights to distribute and use this software
16 ;;;; as governed by the terms of the Lisp Lesser GNU Public License
17 ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
18 ;;;; *************************************************************************
20 (declaim (optimize (debug 3) (speed 3) (safety 1) (compilation-speed 0)))
25 ;;; Some MCL specific utilities
28 ; trap macros don't work right directly in the macros
29 (eval-when (:compile-toplevel :load-toplevel :execute)
36 (defun dispose-ptr (ptr)
40 (defmacro new-ptr (size)
44 (defmacro dispose-ptr (ptr)
50 ;;; Start of standard UFFI
52 (defun size-of-foreign-type (type)
53 "Returns the size for the specified mcl type or record type"
55 (ccl::%foreign-type-or-record-size type :bytes)
57 (let ((mcl-type (ccl:find-mactype type nil t)))
59 (ccl::mactype-record-size mcl-type)
60 (ccl::record-descriptor-length (ccl:find-record-descriptor type t t)) ) ) ) ;error if not a record
64 (defmacro allocate-foreign-object (type &optional (size :unspecified))
65 "Allocates an instance of TYPE. If size is specified, then allocate
66 an array of TYPE with size SIZE."
67 (if (eq size :unspecified)
68 `(new-ptr ,(size-of-foreign-type (convert-from-uffi-type type :allocation)))
69 `(new-ptr (* ,size ,(size-of-foreign-type (convert-from-uffi-type type :allocation))))))
73 (defmacro free-foreign-object (obj)
76 (defmacro null-pointer-p (obj)
77 `(ccl:%null-ptr-p ,obj))
80 (defmacro make-null-pointer (type)
81 (declare (ignore type))
86 (defmacro char-array-to-pointer (obj)
90 (defmacro deref-pointer (ptr type)
91 `(ccl:pref ,ptr ,(convert-from-uffi-type type :deref)))
93 (defmacro deref-pointer-set (ptr type value)
94 `(setf (ccl:pref ,ptr ,(convert-from-uffi-type type :deref)) ,value))
96 (defsetf deref-pointer deref-pointer-set)
99 (defmacro ensure-char-character (obj)
101 #+openmcl `(code-char ,obj))
104 (defmacro ensure-char-integer (obj)
105 #-openmcl `(char-code ,obj)
109 (defmacro pointer-address (obj)
110 `(ccl:%ptr-to-int ,obj))
114 (defmacro with-foreign-objects (bindings &rest body)
115 (let ((params nil) type count)
116 (dolist (spec (reverse bindings)) ;keep order - macroexpands to let*
117 (setf type (convert-from-uffi-type (eval (nth 1 spec)) :allocate))
119 (when (and (listp type) (eq (first type) :array))
120 (setf count (nth 2 type))
121 (unless (integerp count) (error "Invalid size for array: ~a" type))
122 (setf type (nth 1 type)))
123 (push (list (first spec) (* count (size-of-foreign-type type))) params))
124 `(ccl:%stack-block ,params ,@body)))
127 (defmacro with-foreign-object ((var type) &rest body)
128 `(with-foreign-objects ((,var ,type))