Hi all,
beware of FFI 'long' and 'ulong'.
They are currently meaning (32 bits) int and unsigned int!
This dates back from the 80s when there were still odd OS with segmented memory and 16-bits int.
long was thought as a safe int32_t at that time... and still means just that in current FFI.
I'd like to replace them with 'int' and 'uint', but we need to ensure backward compatibility etc...
FFI has ExternalType signedLongLong or just 'longlong' and ExternalType unsignedLongLong or 'ulonglong' which are 64 bits on all architectures.
See implementors of #initializeAtomicTypes #initializeFFIConstants
If you want a type that can hold a pointer on both 32 and 64bits arch, then it's doable with a FFI type alias
For example I have things like this in HDF5 module
Notice the single #(fieldName fieldType) which defines an alias, while ordinary FFI struct gets an array of #(fieldName fieldType)
(and replace Size_t with Intptr_t if the purpose is hodling a pointer, otherwise the ayatollahs of C standard will lash you)
ExternalStructure subclass: #'Size_t'
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'HDF5-External-atomic'
Size_t class >>fields
"Size_t defineFields"
^Smalltalk wordSize = 4
ifTrue: [#( value 'ulong')]
ifFalse: [#( value 'ulonglong')]
However the "fields" must be re-generated when platform changes...
I tried to automate that sometimes ago, see:
ExternalStructure class>>install
"Resuming the image on another architecture may require a re-compilation of structure layout."
| newPlatform |
newPlatform := Smalltalk platformName.
PreviousPlatform = newPlatform
ifFalse:
[self recompileStructures.
PreviousPlatform := newPlatform]
It works if you switch from Win64 to MacOS64 for example...
However, this mechanism is not used yet at time of code loading, so importing code generated on a different platform won't automatically update the structures (or alias) - the FFI package has no mechanism for that (maybe we could add a hook in MC?).