Referring to the example show_clang_version() below, cleanup is done
with clang_disposeString(). How does UFFI hook into the object
finalisation mechanism to call this when the object is garage
collected.  My searches result mostly in info on weak collections and
its not clear how this translates to FFI.  Some detail on this would
be useful for the FFI manual .

cheers -ben

On Thu, Sep 1, 2016 at 12:59 AM, Ben Coman <b...@openinworld.com> wrote:
> 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