produces an error ==> FFIDereferencedOpaqueObjectError.
because..."external objects have a natural arity of zero but they MUST be called with some arity,
because they are actually external addresses (pointers) and you need to always declare external objects as this example:
�� ��self ffiCall: #( FFIExternalObject *c_function ( FFIExternalObject *handle ) ) ��
"
which is enforced by...
�� FFIOpaqueObjectType>>validateAfterParse: typeAndArityTuple
�� �� �� self pointerArity >= 1 ifTrue: [ ^ self ]. ��"@0"
�� �� �� typeAndArityTuple second >= 1 ifTrue: [ ^ self ].
�� �� �� FFIDereferencedOpaqueObjectError signal
where pointerArity seems set earlier just by counting the number of pointer stars in the functions return type, which in this case is none...
�� FFICallout>>resolveType: aTypeName �� "aTypeName==> 'CXIndex' "
�� �� �� | name newName resolver binding ptrArity |
�� �� �� newName := aTypeName.
�� �� �� ptrArity := 0.
�� �� �� "resolve aliases and pointers"
�� �� �� [
�� �� �� �� �� �� name := newName asString trimRight. ��
�� �� �� �� �� �� newName := self aliasForType: name.
�� �� �� �� �� �� newName last = $* ifTrue: [
�� �� �� �� �� �� �� �� �� ptrArity := ptrArity + 1.
�� �� �� �� �� �� �� �� �� newName := newName allButLast ].
�� �� �� �� �� �� name = newName
�� �� �� ] whileFalse.
�� �� �� resolver := requestor ifNil: [ self class ]. �� ��"resolver==> CXIndex class"
�� �� �� binding := resolver ffiBindingOf: name asSymbol. �� "binding==> #CXIndex->CXIndex"
�� �� �� binding ifNotNil: [
�� �� �� �� �� ^ (binding value "@1" asExternalTypeOn: self) "@2" pointerArity: ptrArity ] .
which @1 invokes...
�� CXIndex(FFIOpaqueObject) class >> asExternalTypeOn: generator
�� �� �� ��^ FFIOpaqueObjectType objectClass: self
�� FFIOpaqueObjectType(FFIExternalReferenceType) class >> objectClass: aClass
�� �� �� ^ self new objectClass: aClass �� ����
����
�� FFIOpaqueObjectType(FFIExternalReferenceType) >> objectClass: aClass
objectClass := aClass. �� ��"aClass==>CXIndex"
�� �� �� �� pointerArity := 0. ��"actually this was done in #initialize" ����"@3"
Thus FFIOpaqueObjectType(CXIndex) is returned��@2 which invokes...
�� FFIOpaqueObjectType(FFIExternalType)>>pointerArity: additionalArity
pointerArity := pointerArity + additionalArity.
which sets pointerArity ==> 0.
But I hazard to suggest that...
�� �� typedef void *CXIndex;
should make pointerArity:=1 when��objectClass is assigned @3.����
So I hacked around this by....
�� FFIExternalReference class >> pointerArity
�� �� �� ^0
�� CXIndex class >> pointerArity
�� �� �� ^1
����
�� FFIExternalReferenceType >> objectClass: aClass
objectClass := aClass.
pointerArity := aClass pointerArity.
but I wonder if this is the best way, or if external references these opaque objects should have a class-side method similar to #fieldDesc like...��
�� �� typedef ��
�� �� �� ��^#( void * )
Thus CXIndex create "==> a CXIndex((void*)@ 16rB6D514A8)"
I am yet to test out this returned object by passing it to another C-library function, but I thought the above was enough for one sitting.
P.S. Further background...