[squeak-dev] FFI question: array of structures as parameter

Douglas McPherson djm1329 at san.rr.com
Tue Jun 12 04:47:05 UTC 2012


Awesome. I took at a look at ExternalArray and its subclasses. This is exactly what I was looking for! In fact I think the implementation of ExternalDoubleComplexArray does the exact type of thing I need, which is provide the ability to marshal an array of ExternalStructure to/from an underlying byte array. 

I've never looked at Smallapack till now. Do you think that ExternalArray etc should be made part of FFI, since it has uses beyond just Smallapack? Are there caveats? I notice that many methods have a comment like "Use with caution ! Might result in segmentation fault". Is this because of verification limitations, alignment issues, or are there other concerns as well?

Nice, nice :)

Thanks,
Doug


On Jun 10, 2012, at 13:00 , Nicolas Cellier wrote:

> AFAIK, you'll have to use void * in API because arrays of structures
> are not supported.
> I mean FFI is not able to perform any type verification on array of
> structures...
> 
> I created this class in Smallapack:
> 
> ArrayedCollection subclass: #ExternalArray
> 	instanceVariableNames: 'handle size data'
> 	classVariableNames: 'EndianCache'
> 	poolDictionaries: ''
> 	category: 'Smallapack-Collection'
> 
> - handle holds the pointer (ExternalAddress),
> - size the number of elements,
> - data is the object to be passed to the foreign function call (it
> holds address + type information).
> And here is how I had to initialize data:
> 
> resetExternalData
> 	"Reset the ExternalData object used as FFI argument.
> 	This is cached in an inst-var instead of being recreated at each call.
> 	However, this must be reset whenever handle is changed"
> 	| cType |
> 	cType := self class type.
> 	data := cType isStructureType
> 		ifTrue:
> 			["Arrays of structure cannot carry type checking in FFI"
> 			ExternalData fromHandle: handle type: ExternalType void]
> 		ifFalse:
> 			["Atomic types"
> 			ExternalData fromHandle: handle type: self class type]
> 
> Nicolas
> 
> 2012/6/10 Douglas McPherson <djm1329 at san.rr.com>:
>> All,
>> 
>> I'm trying to call a function in an external library which takes an array of
>> structures as one of its parameters. I can see how to define a subclass of
>> ExternalStructure, and how that creates convenient field accessors which
>> read/write an underlying ByteArray. I can see how to use such an
>> ExternalStructure to pass the struct, or a pointer to it, to a function in
>> the library. Is there a similar object I can create which allows me to
>> read/write an array of these structs (i.e. does the proper marshaling
>> to/from a ByteArray)?
>> 
>> I got the i/f working by rolling my own -- directly filling up a ByteArray
>> with the right number of instances of the serialized-by-hand structure,
>> creating an ExternalData instance with said ByteArray as the handle, and
>> passing this as the parameter. But this doesn't allow me to use the field
>> accessor methods created by ExternalStructure, so it feels like I'm missing
>> something.
>> 
>> For concreteness, the API looks something like this:
>> 
>> typedef struct
>> {
>> uint32_t someId;
>> int32_t  someInt;
>> } fooStruct;
>> 
>> int32_t apiFunction
>> (
>> const  fooStruct *foo_list,
>> uint32_t foo_list_size
>> );
>> 
>> Any suggestions?
>> 
>> Thanks,
>> Doug
>> 
>> 
>> 
> 



More information about the Squeak-dev mailing list