[Openmcl-devel] How do I initialize an array of structs? (FFI)

Gary Byers gb at clozure.com
Sat Jan 8 20:40:07 PST 2005



On Sat, 8 Jan 2005, David Steuber wrote:

> On Jan 8, 2005, at 3:17 AM, David Steuber wrote:
>
> > Give this C fragment:
> >
> > EventTypeSpec moonSpec[] = {{kEventClassCommand, kEventCommandProcess},
> >   {kEventClassWindow, kEventWindowClose}};
> >
> > How do I initialize moonspec in the following rlet?
> >
> >   (rlet ((nibref :<ibn>ib<r>ef)
> >          (mainspec :<e>vent<t>ype<s>pec
> >                    :event<c>lass #$kEventClassCommand
> >                    :event<k>ind #$kEventCommandProcess)
> >          (moonspec (:array :<e>vent<t>ype<s>pec 2)))
> >     ...)
> >
> > I tried doing it in the rlet until I found this:
> >
> > " When the type is an array,  initforms  may  not be provided, because
> >  make-record   cannot initialize its values.  make-record   is also
> > unable to initialize fields of a  struct   which are themselves
> > struct   s. The user of   make-record   should set these values  by
> > another means."
>
> Ok, after much hunting through the docs and a couple of aborted
> attempts, I came up with this:
>
>    (rlet ((nibref :<ibn>ib<r>ef)
>           (mainspec :<e>vent<t>ype<s>pec
>                     :event<c>lass #$kEventClassCommand
>                     :event<k>ind #$kEventCommandProcess)
>           (moonspec (:array :<e>vent<t>ype<s>pec 2)))
>      (let ((offset 0))                                 ; initialize
> moonspec the only way I know how
>        (dolist (sfv (list #$kEventClassCommand #$kEventCommandProcess
> #$kEventClassWindow #$kEventWindowClose))
>          (setf (ccl::%get-unsigned-long moonspec offset) sfv)
>          (incf offset (ccl::record-length :unsigned))))
>
> I had a bit of confusion over two points.  #$Foo becomes OS::|Foo| so
> using a quoted list didn't work like I thought it would, hence LIST.  I
> also thought %GET-UNSIGNED-WORD would be 32 bits, not 16.  Oops.  Both
> facts are documented though, the latter in 9.3.2.1 in the OpenMCL
> documentation.
>
> Is this the best way to do this?

Unfortunately, yes.

Someone told me several weeks ago that they'd fixed PREF and friends
to do the address arithmetic for you, so that you'd be able to say
something like:

   (setf (pref array-ptr 0) val-0
         (pref array-ptr 1) val-1)

[I'm not exactly sure what the syntax would/should be; you might have
to provide more type information in the PREF form, but it should still
be simpler/clearer if PREF was macroexpanding into the right code for
you.]

The person who said that he'd fixed PREF works for an institution that
requires careful review of all internally developed code before releasing
it publicly; hopefully, whoever does that review will soon discover
that this isn't likely to be a matter of national security.



More information about the Openmcl-devel mailing list