For this definition pulled from a library header file...
    typedef struct {
        const void *data;
        unsigned private_flags;
    } CXString;

which is used with a helper function to get a usable string like...
  void show_clang_version(void)
  {    CXString version = clang_getClangVersion();
       printf("%s\n", clang_getCString(version));
       clang_disposeString(version);
  }

==> 'Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on
LLVM 3.5.0)'


So I defined...
    FFIExternalStructure subclass: #CXString
        instanceVariableNames: ''
        classVariableNames: ''
        package: 'LibCLang'

and ignoring the const as advised in the manual [1],  I try...
    CXString class >> fieldsDesc
    ^ #(
         void *data;
         unsigned private_flags;
         )

but...
    CXString rebuildFieldAccessors.
    ==>Error: Unable to resolve external type: unsigned

I also tried  "unsigned int private_flags;"
but get the same error. Any ideas what is wrong?


Actually I can kind of ignore creating accessors since this is like an
opaque type where I'm not expected to access its internals, but I do
need CXString as a return value like this...

  LibCLang class >> getClangVersion
     ^ self ffiCall: #( CXString clang_getClangVersion () ) module: LibCLang

which needs to be passed to this function to get a workable string....

  LibCLang class >> getString: aCXString
     ^ self ffiCall: #( String clang_getCString ( CXString aCXString )
) module: LibCLang

However this doesn't work if I use FFIOpaqueObject instead of
FFIExternalStructure.
I guess the difference is opaque objects are normally pointers to a
type, whereas here that pointer is contained in a struct.

What I've done at the moment to push ahead with experimenting is avoid
needing to generate accessors by adding...

   CXString >> printOn: asStream
        self getString printOn: aStream

    CXString >> getString
        ^ self ffiCall: #( String clang_getCString ( CXString self ) )
module: LibCLang

such that...
   LibCLang getClangVersion "<Print It>"
   ==> 'Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based
on LLVM 3.5.0)'


Is there a better way to approach this?

cheers -ben

btw, this is in Pharo 5 (Moose 6).

[1] 
https://ci.inria.fr/pharo-contribution/view/Books/job/PharoBookWorkInProgress/lastSuccessfulBuild/artifact/book-result/UnifiedFFI/UnifiedFFI.pdf

Reply via email to