[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,
Cyrus
> 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