[Openmcl-devel] Idiom for creating arrays of C structs
millejoh at mac.com
Thu Jun 4 06:34:19 PDT 2009
Thank you! Everything works quite nicely now. If my brain hadn't
filled up after reading the first few paragraphs of your explanation I
am quite sure I would have learned a number of very interesting things.
On Jun 3, 2009, at 1:56 AM, Gary Byers wrote:
> In C, a "vector of structs" is very different from "a vector of
> to structs"; I'm pretty sure (from the parts of the code that I can
> that what we're dealing with here is "an array of cpv structs" rather
> than "an array of pointers to cpv structs."
> If P is a pointer to an array of cpv structs, then in order to access
> the I'th element of P by adding (* I <size of cpv struct>) to the
> of P; the resulting pointer would be a pointer to the I'th struct.
> In CCL's FFI, that'd be:
> (%INC-PTR ptr-returned-from-make-cpv-array (* index size-of-cpv-
> And to access the value of the X component of the INDEX'th CPV struct,
> (pref (%INC-PTR ptr-returned-from-make-cpv-array (* index size-of-
> #>cpVect.x) ; or whatever.
> There's an internal, undocumented function named CCL::%COMPOSITE-
> it exists solely to allow SETF to work with some macros and allows
> like "setting the I'th element of an array of structures to the
> value of
> another structure", which is pretty obscure. If you see calls to
> CCL::%COMPOSITE-POINTER-REF in some macroexpansions, they'd probably
> best read as if they were %INC-PTR calls.
> There's a little bit of syntactic sugar (another thing that may be
> in the old release notes in the doc directory but may not have made
> it into
> the manual) that can make this a little easier:
> (CCL:PAREF array-pointer array-foreign-type index)
> Hopefully, the other arguments are self-explanatory; somewhat
> strangely, PAREF
> expects the ARRAY-FOREIGN-TYPE argument to be the type of the array
> (a pointer
> to something), rather than the type of its elements.
> ? (def-foreign-type nil
> (:struct example
> (x :double-float)
> (y :double-float)))
> ? (ccl:macroexpand-all '(pref (paref p (:* (:struct :example))
> 17) :example.x))
> (%GET-DOUBLE-FLOAT (%COMPOSITE-POINTER-REF 16 P (/ (THE FIXNUM (*
> 128 (THE FIXNUM 17))) 8)) (/ 0 8))
> which looks a lot scarier than it is.
> On Tue, 2 Jun 2009, John Miller wrote:
>> Are there any conventions/best practices to follow when working
>> with arrays of C structs that are passed back and forth from
>> foreign code? Sorry if this has already been discussed in the
>> past, but nothing jumped out at me while browsing through the
>> group's archives.
>> The code in the attached file seems to work on first appearance,
>> creating an array of cpVect structures on a call to make-cpv-
>> array. I can do something like
>> (%get-ptr ptr-returned-from-make-cpv-array (* index size-of-cpv-
>> and get a cpVect structure back. When I pass the MACPTR returned
>> by make-cpv-array to foreign code, however, the block of memory
>> apparently turns to mush. A copy of the C code I am calling with
>> my make-cpv-array MACPTR is also in the attached file along with
>> some interactions with the Listener.
>> I guess that #<A Foreign Pointer (:* (:STRUCT :CP<V>ECT))
>> #x1EF61470> is not the same as a cpVect* verts, but I am at a loss
>> to explain why and how to get the two to agree.
More information about the Openmcl-devel