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 |
Hi,
(Short because I'm by phone) Const should be ignored so you can keep it (if not is a bug) Unsigned does not exist :) You can always put an alias, but the type you are looking for is "uint" Cheers, Esteban > On 31 Aug 2016, at 18:59, Ben Coman <[hidden email]> 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 > |
Thanks Esteban. That worked.
However it may be good to be more permissive about allowing const to reduce the surprises for FFI users. Same for unsigned. Reviewing FFIExternalStructureFIeldParser>>praseFields:structure: I see declarations are parsed simply left-to-right, which okay as the simplest-thing-that-would-work. However (in case I get inspired...), would this benefit from more complex parsing like described at [1] and [2]? Or is this unlikely to be a concern in prcatice, and/or the rest of FFI not ready receive such complex declarations from the parser? [1] http://www.geeksforgeeks.org/complicated-declarations-in-c/ [2] http://unixwiz.net/techtips/reading-cdecl.html cheers -ben On Thu, Sep 1, 2016 at 2:01 AM, Esteban Lorenzano <[hidden email]> wrote: > Hi, > > (Short because I'm by phone) > > Const should be ignored so you can keep it (if not is a bug) > Unsigned does not exist :) > You can always put an alias, but the type you are looking for is "uint" > > Cheers, > Esteban > >> On 31 Aug 2016, at 18:59, Ben Coman <[hidden email]> 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 >> > |
well, I accept contributions :)
I was thinking about enhance the parser too (but for allowing array declarations, not for unsigned)… anyway, as soon as tests passes and backward compatibility is there, I would like to have a better parser, yes. cheers, Esteban > On 01 Sep 2016, at 18:40, Ben Coman <[hidden email]> wrote: > > Thanks Esteban. That worked. > > However it may be good to be more permissive about allowing const to > reduce the surprises for FFI users. Same for unsigned. > > Reviewing FFIExternalStructureFIeldParser>>praseFields:structure: > I see declarations are parsed simply left-to-right, which okay as the > simplest-thing-that-would-work. However (in case I get inspired...), > would this benefit from more complex parsing like described at [1] and > [2]? Or is this unlikely to be a concern in prcatice, and/or the rest > of FFI not ready receive such complex declarations from the parser? > > [1] http://www.geeksforgeeks.org/complicated-declarations-in-c/ > [2] http://unixwiz.net/techtips/reading-cdecl.html > > cheers -ben > > On Thu, Sep 1, 2016 at 2:01 AM, Esteban Lorenzano <[hidden email]> wrote: >> Hi, >> >> (Short because I'm by phone) >> >> Const should be ignored so you can keep it (if not is a bug) >> Unsigned does not exist :) >> You can always put an alias, but the type you are looking for is "uint" >> >> Cheers, >> Esteban >> >>> On 31 Aug 2016, at 18:59, Ben Coman <[hidden email]> 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 >>> >> > |
Free forum by Nabble | Edit this page |