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

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Sun Jun 10 20:00:44 UTC 2012


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