[Openmcl-devel] another make-record question

Cyrus Harmon ch-openmcl at bobobeach.com
Fri Aug 20 10:18:10 PDT 2004

On Aug 20, 2004, at 9:16 AM, Gary Byers wrote:

> You could do something like (this steals code from MAKE-RECORD 
> verbatim):
> (defun allocate-record (record-or-type-name)
>   (let* ((ftype (ccl::%foreign-type-or-record record-or-type-name))
>          (bits (ccl::enxure-foreign-type-bits ftype))
>          (bytes (if bits
> 		  (ceiling bits 8)
> 		  (error "Unknown size for foreign type ~S."
> 			 (ccl::unparse-foreign-type ftype))))
>          (p (#_malloc bytes)))
>      (if (%null-ptr-p p)
>        (error "Couldn't malloc ~d bytes." bytes))
>      (#_bzero p bytes)
>      p))

Indeed, this seems to do what I need. But is this the right way to go?

> CCL::%FOREIGN-TYPE-OR-RECORD will map a foreign type specifier or
> record name  to a data structure that represents that type or record
> (perhaps looking in the interface database, i.e., the .cdb files).
> Consider a scenario where this is called in a standalone application.
> Should the author of that application be required to distribute the
> interface database with the application ?  (That's not illegal or
> immoral or anything, and to some extent it's also a rhetorical
> question.)

Hmm... I think I understand where you're going with this. If I 
understand it, there is a certain amount of stuff that is best done at 
macro-expansion time. Would it be possible to decouple the type/record 
information from the malloc'ing? Essentially, instead of wrapping 
make-instance, as proposed below, I would prefer to continue to let the 
user (me) call make-instance, but force the developer (also me) to do 
some work at macro-expansion, like a register-record-or-type-name that 
would compute and save the type/record stuff for use by a 
make-record-like function to be called with impunity at runtime, 
provided the types had been registered at macro-expansion time. Does 
this make any sense?

Thanks again,


> Note that all that we're doing at this point is determining the
> size of the foreign type/record so that we can call #_malloc and
> #_bzero with the right args.  I realize that there might be other
> reasons for wanting information about a type/record in the system
> you're working on, but this can be handled via some macrology:
> (defmethod initialize-instance ((obj encapsulating-object)
>                                 &key record-size-in-bytes
>                                 &allow-other-keys)
>   (with-slots (foreign-pointer) obj
>     (setq foreign-pointer (#_malloc record-size-in-bytes))))
> It'd be awkward to have to say
> (make-instance 'encapsulating-object :record-size-in-bytes 17)
> but might be less awkward if the user used a macro and rarely called
> MAKE-INSTANCE directly:
> (defmacro make-encapsulating-object (foreign-type)
>   ;;; Do type -> record-size-in-bytes as in MAKE-RECORD/ALLOCATE-RECORD
>   (let* ((...)
>          (size-in-bytes (ceiling bits 8)))
>   `(make-instance 'encapsulating-object :record-size-in-bytes 
> ,size-in-bytes)))

More information about the Openmcl-devel mailing list