My bindings for GLib/GTK+ etc. involve some functions with 64 bit parameter/return values, using the C types gint64/guint64 - GLib's portable 64 bit integers. On Linux i386, these types are defined using 'signed/unsigned long long int'. I believe the C library stdint.h defines portable types too, e.g. int64_t. (C99 provides 'long long int' that is defined to be at least 64 bits.)
At present, I am working on GNU/Linux x86_64 where 'long' is 64 bits, so the conversion LONG can be used to pass 64 bit values over the FFI. However, I can't see a way to pass 64 bit values on platforms where 'long' is not 64 bits. Is there a way? I have no immediate need, but I'm thinking that support for e.g. Linux i386 would be desirable at some point.
Conversions such as LONGLONG/ULONGLONG could provide the FFI capability on i386, where 'long long' is 64 bits. However, SML applications would still need to choose between LONG and LONGLONG if 'long long' is larger. So conversions such as INT64/UINT64 for exactly 64 bits on any platform may be a better approach for a portable 64 bit C type. If I have a moment, I'll have a look at foreign.cpp to see what is involved.
Phil
On 08/08/2012 22:51, Phil Clayton wrote:
My bindings for GLib/GTK+ etc. involve some functions with 64 bit parameter/return values, using the C types gint64/guint64 - GLib's portable 64 bit integers. On Linux i386, these types are defined using 'signed/unsigned long long int'. I believe the C library stdint.h defines portable types too, e.g. int64_t. (C99 provides 'long long int' that is defined to be at least 64 bits.)
At present, I am working on GNU/Linux x86_64 where 'long' is 64 bits, so the conversion LONG can be used to pass 64 bit values over the FFI. However, I can't see a way to pass 64 bit values on platforms where 'long' is not 64 bits. Is there a way? I have no immediate need, but I'm thinking that support for e.g. Linux i386 would be desirable at some point.
Conversions such as LONGLONG/ULONGLONG could provide the FFI capability on i386, where 'long long' is 64 bits. However, SML applications would still need to choose between LONG and LONGLONG if 'long long' is larger. So conversions such as INT64/UINT64 for exactly 64 bits on any platform may be a better approach for a portable 64 bit C type. If I have a moment, I'll have a look at foreign.cpp to see what is involved.
I think it would probably be a good idea to add a range of conversions with and without explicit lengths, e.g. UINT64, LONGLONG and also possibly INT_PTR and UINT_PTR. I don't think it's difficult to do: it needs changes in foreign.cpp in various places and also additions in the higher-level parts of CInterface. I've added a few extra conversions, such as "unsigned" at one time or another.
David
On 10/08/12 09:51, David Matthews wrote:
On 08/08/2012 22:51, Phil Clayton wrote:
My bindings for GLib/GTK+ etc. involve some functions with 64 bit parameter/return values, using the C types gint64/guint64 - GLib's portable 64 bit integers. On Linux i386, these types are defined using 'signed/unsigned long long int'. I believe the C library stdint.h defines portable types too, e.g. int64_t. (C99 provides 'long long int' that is defined to be at least 64 bits.)
At present, I am working on GNU/Linux x86_64 where 'long' is 64 bits, so the conversion LONG can be used to pass 64 bit values over the FFI. However, I can't see a way to pass 64 bit values on platforms where 'long' is not 64 bits. Is there a way? I have no immediate need, but I'm thinking that support for e.g. Linux i386 would be desirable at some point.
Conversions such as LONGLONG/ULONGLONG could provide the FFI capability on i386, where 'long long' is 64 bits. However, SML applications would still need to choose between LONG and LONGLONG if 'long long' is larger. So conversions such as INT64/UINT64 for exactly 64 bits on any platform may be a better approach for a portable 64 bit C type. If I have a moment, I'll have a look at foreign.cpp to see what is involved.
I think it would probably be a good idea to add a range of conversions with and without explicit lengths, e.g. UINT64, LONGLONG and also possibly INT_PTR and UINT_PTR.
Yes, that does sound good.
I have found the following tables on the MLton website useful: http://mlton.org/ForeignFunctionInterfaceTypes (I'm not sure that there is any need to distinguish between an implicit and explicit signed qualifier though.)
I don't think it's difficult to do: it needs changes in foreign.cpp in various places and also additions in the higher-level parts of CInterface. I've added a few extra conversions, such as "unsigned" at one time or another.
I had spotted those additions but haven't tried anything myself. To save on effort, I was wondering about using sizes supplied by autoconf for the platform-dependent types, so that they can be defined in terms of the portable types or vice-versa.
Phil
On 10/08/12 14:52, Phil Clayton wrote:
On 10/08/12 09:51, David Matthews wrote:
I think it would probably be a good idea to add a range of conversions with and without explicit lengths, e.g. UINT64, LONGLONG and also possibly INT_PTR and UINT_PTR.
Yes, that does sound good.
I have found the following tables on the MLton website useful: http://mlton.org/ForeignFunctionInterfaceTypes (I'm not sure that there is any need to distinguish between an implicit and explicit signed qualifier though.)
Actually, regarding char, the C99 standard states:
The implementation shall define char to have the same range, representation, and behaviour as either signed char or unsigned char.
So CHAR, SCHAR and UCHAR would make sense.
Phil