I have a type definition...
�� ��typedef void *CXIndex;

which I believe reads "CXIndex is a pointer at void"
that is returned by...
�� �� CXIndex clang_createIndex(int x, int y)

This seems an obvious candidate to be a FFIOpaqueObject defined like this...

�� FFIOpaqueObject subclass: #CXIndex
�� �� �� instanceVariableNames: ''
�� �� �� classVariableNames: ''
�� �� �� package: 'LibclangPractice'

�� CXIndex class >> create
�� �� �� ^ self ffiCall: #( CXIndex clang_createIndex ( 0, 0 ) )

however ��"CXIndex create inspect"
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.

cheers -ben


P.S. Further background...

Declarations...
�� �� typedef void *CXIndex; ��
�� �� CXIndex clang_createIndex(int xx, int yy));
defined at...
https://github.com/llvm-mirror/clang/blob/release_39/include/clang-c/Index.h

and definition is at...��
https://github.com/llvm-mirror/clang/blob/release_39/include/clang-c/Index.h

�� ��extern "C" {
�� �� �� CXIndex clang_createIndex( ��) {
�� �� �� �� �� ��...
�� �� �� �� �� ��CIndexer *CIdxr = new CIndexer();
�� �� �� �� �� ��...
�� �� �� �� �� ��return CIndexer;
�� �� ��} }