Following on from my "Parting words" at [1] I'd like to add the following...
�� FFIExternalEnumerationType >>��callbackReturnOn: callbackContext for: anObject
�� �� �� ^ super callbackReturnOn: callbackContext for: anObject value
but I'm seeking some expert feedback before logging an issue.
For discussion background, here is a reference C program that sets up the framework for a callback that returns an enumeration...
----------example.c
�� #include <stdio.h>
�� typedef enum {
�� �� A = 1,
�� �� B = 2,
�� �� C = 3
�� } CallBackReturnValue;
�� CallBackReturnValue callbackFn() {
�� �� return B;
�� }
�� CallBackReturnValue callout( CallBackReturnValue (*callback)() )
�� {
�� �� return callback();
�� }
�� int main()
�� {
�� �� printf("%d\n", callout(callbackFn) );
�� �� return 0;
�� }
----------
And validation...
$ gcc ��-Wall -Werror ��example.c
$ ./a.out��
2
----------
Now after deleting main() and callback(), then compiling to a shared library per [2]...
$ gcc ��-c ��-Wall ��-Werror ��-fpic ��example.c
$ gcc ��-shared ��-o passthru.so ��example.o
$ cp ��example.so �� /tmp
the Pharo equivalent is....
FFIExternalEnumeration subclass: #CallBackReturnValue
instanceVariableNames: ''
classVariableNames: ''
package: 'AAAExample'
CallBackReturnValue class >>��enumDecl
�� �� ^ #( A 1
�� �� �� B 2
�� �� ��C 3 )
CallBackReturnValue class >> initialize
self initializeEnumeration
And evaluate "CallBackReturnValue initialize."
FFILibrary subclass: #Example
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: 'CallBackReturnValue'
package: 'AAAExample'
Example >>��unixModuleName
^ '/tmp/example.so'
Example class >>��callout: callbackBlock
^ self ffiCall: #( int callout ( FFICallback callbackBlock ) ) module: Example
Example class >> doCallback
| callbackFn |
callbackFn :=��
�� FFICallback
signature: ��#( CallBackReturnValue ( void ) )
block: [ B ].
^ Example callout: callbackFn.
-----
But "Example doCallback"
produces error in VMCallbackContext32>>wordResult: anInteger
where anInteger is aCallBackReturnValue(#B)
rather than 2
I can resolve this using...��
callbackFn :=��
���� FFICallback
signature: ��#( CallBackReturnValue ( void ) )
block: [ B value ]. "<==="
but the original direct use of the enumeration "B" directly is nicer.��
This can be facilitated by moving #value as follows...
�� FFIExternalEnumerationType >>��callbackReturnOn: callbackContext for: anObject
�� �� �� ^ super callbackReturnOn: callbackContext for: anObject value "<=="
��
where the existing method for super is...
�� FFIExternalType >> callbackReturnOn: callbackContext for: anObject
^ callbackContext wordResult: anObject
Anyone see a problem with that addition?
btw, Would that example be useful for the book?
cheers -ben