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; } }