# Tcl cffi package
The Tcl `cffi` package permits calling C functions in shared libraries
from within Tcl scripts via either the `libffi` or `dyncall` open source libraries.
The package source repository is at https://github.com/apnadkarni/tcl-cffi.
Documentation is at https://cffi.magicsplat.com. Some additional
tutorial material is available at
https://www.magicsplat.com/blog/tags/cffi/ and the samples in https://github.com/apnadkarni/tcl-cffi/tree/main/examples.
Source distributions and binary packages for some platforms can be
downloaded from https://sourceforge.net/projects/magicsplat/files/cffi.
## Building
To build the package from the source, see the `BUILD.md` file in the repository or source distribution.
## About the package
Major features of the package are
- Implicit conversions of numerics, strings, structs and arrays
- Safety mechanisms for pointers
- Automatic encoding of string values passed and returned from C functions
- Exception generation based on C function return values
- Proc-like argument processing with defaults, error messages etc.
- Utilities for managing memory and conversion to native formats
- Extensible type aliases and enums
- Introspection
Limitations in the current version include
- No support of functions taking variable number of arguments
## Changes in 1.0b4
- Added `callback` and `callback_free` commands for supporting callbacks
from C functions.
- Program element names are now scoped based on namespace at definition
time.
- New methods `set` and `get` for `Struct` instances to store and
retrieve fields in native structs in memory.
- New method `fromnative!` method for `Struct` instances.
- New method `fieldpointer` to retrieve the pointer to a field in a
native struct.
- Support `string` and `unistring` types for struct fields.
- Support default values and `-clear` option for `Struct` fields.
- Support `enum` and `bitmask` annotations for struct field types as for function parameters.
- Allow enum literals in type declarations in addition to defined enums.
- New commands `enum clear` and `enum flags`.
- New command `alias clear`.
- The `memory allocate` command now accepts a type declaration for
specifying allocation size.
- New commands `memory set`, `memory set!`, `memory get` and `memory
get!` to store and retrieve typed values in native form.
- Zero size dynamic arrays are passed as NULL pointers.
- The `byref` annotation is now permitted on return types to implicitly dereference pointers returned by functions.
- New command `limits` to retrieve range of integer types.
- Support arrays of `string` and `unistring` types.
- New command `pointer make`.
- **Incompatibility** `memory set` command renamed to `memory fill`.
- **Incompatibility** The format and content of type information
returned by `type info` has changed.
- **Incompatibility** Commands that accept patterns only treat last
component in a program element name as a pattern.
## Changes in 1.0b3
- **Incompatibility** `cffi::dyncall::Library` class renamed to `cffi::Wrapper` as it is no longer specific to `dyncall`.
- **Incompatibility** The `cffi::dyncall::Symbols` class has been removed.
- Added support for the `libffi` library back end as an alternative to `dyncall`. The selection is made at build time. See `BUILD.md` in the
source distribution.
- C structs can be returned from functions and passed by value if the `libffi` back end is being used. This is still not supported with
`dyncall` library.
## Changes in 1.0b1
- **Incompatibility** Null pointers will now raise a Tcl exception when passed as arguments or returned from functions unless the `nullok`
annotation is present. Related to this, the `nonzero` annotation can no longer be applied to
pointers.
- **Incompatibility** The format of arguments passed to `onerror`
handler has changed.
- The `onerror`, `lasterror` and `errno` annotations can be included on parameter definitions and are ignored. This permits common type aliases
for return values and paramters.
- The `alias define` command now allows multiple alias definitions to be passed.
## Changes in 1.0b0
- Added `help` command for wrapped function list and syntax
- Added `enum value` and `enum name` to map enumeration values and names
- Map enum values for output parameters and return values
- Support arrays for pointers and structs
## Changes in 1.0a7
- Support `string`, `unistring` and `binary` as return types and output parameters
- Support `nonzero` annotation for strings and unistrings
- Added `enum` command to define constants and enumerations
- Added `bitmask` annotation for integer parameters
- Added `onerror` annotation for custom error handlers
- Added `disposeonsuccess` annotation to only invalidate pointers on success - Sample `libzip` wrapper in examples directory
- Miscellaneous bug fixes. See https://github.com/apnadkarni/tcl-cffi/milestone/1?closed=1 for a full list.
On Tuesday, February 8, 2022 at 9:39:45 PM UTC-8, apn wrote:
# Tcl cffi package
The Tcl `cffi` package permits calling C functions in shared libraries
from within Tcl scripts via either the `libffi` or `dyncall` open source libraries.
The package source repository is at https://github.com/apnadkarni/tcl-cffi.
Documentation is at https://cffi.magicsplat.com. Some additional
tutorial material is available at https://www.magicsplat.com/blog/tags/cffi/ and the samples in https://github.com/apnadkarni/tcl-cffi/tree/main/examples.
Source distributions and binary packages for some platforms can be downloaded from https://sourceforge.net/projects/magicsplat/files/cffi.
## Building
To build the package from the source, see the `BUILD.md` file in the repository or source distribution.
## About the package
Major features of the package are
- Implicit conversions of numerics, strings, structs and arrays
- Safety mechanisms for pointers
- Automatic encoding of string values passed and returned from C functions - Exception generation based on C function return values
- Proc-like argument processing with defaults, error messages etc.
- Utilities for managing memory and conversion to native formats
- Extensible type aliases and enums
- Introspection
Limitations in the current version include
- No support of functions taking variable number of arguments
## Changes in 1.0b4
- Added `callback` and `callback_free` commands for supporting callbacks from C functions.
- Program element names are now scoped based on namespace at definition time.
- New methods `set` and `get` for `Struct` instances to store and
retrieve fields in native structs in memory.
- New method `fromnative!` method for `Struct` instances.
- New method `fieldpointer` to retrieve the pointer to a field in a
native struct.
- Support `string` and `unistring` types for struct fields.
- Support default values and `-clear` option for `Struct` fields.
- Support `enum` and `bitmask` annotations for struct field types as for function parameters.
- Allow enum literals in type declarations in addition to defined enums.
- New commands `enum clear` and `enum flags`.
- New command `alias clear`.
- The `memory allocate` command now accepts a type declaration for specifying allocation size.
- New commands `memory set`, `memory set!`, `memory get` and `memory
get!` to store and retrieve typed values in native form.
- Zero size dynamic arrays are passed as NULL pointers.
- The `byref` annotation is now permitted on return types to implicitly dereference pointers returned by functions.
- New command `limits` to retrieve range of integer types.
- Support arrays of `string` and `unistring` types.
- New command `pointer make`.
- **Incompatibility** `memory set` command renamed to `memory fill`.
- **Incompatibility** The format and content of type information
returned by `type info` has changed.
- **Incompatibility** Commands that accept patterns only treat last component in a program element name as a pattern.
## Changes in 1.0b3
- **Incompatibility** `cffi::dyncall::Library` class renamed to `cffi::Wrapper` as it is no longer specific to `dyncall`.
- **Incompatibility** The `cffi::dyncall::Symbols` class has been removed.
- Added support for the `libffi` library back end as an alternative to `dyncall`. The selection is made at build time. See `BUILD.md` in the source distribution.
- C structs can be returned from functions and passed by value if the `libffi` back end is being used. This is still not supported with
`dyncall` library.
## Changes in 1.0b1
- **Incompatibility** Null pointers will now raise a Tcl exception when passed as arguments or returned from functions unless the `nullok` annotation is present. Related to this, the `nonzero` annotation can no longer be applied to
pointers.
- **Incompatibility** The format of arguments passed to `onerror`
handler has changed.
- The `onerror`, `lasterror` and `errno` annotations can be included on parameter definitions and are ignored. This permits common type aliases
for return values and paramters.
- The `alias define` command now allows multiple alias definitions to be passed.
## Changes in 1.0b0
- Added `help` command for wrapped function list and syntax
- Added `enum value` and `enum name` to map enumeration values and names
- Map enum values for output parameters and return values
- Support arrays for pointers and structs
## Changes in 1.0a7
- Support `string`, `unistring` and `binary` as return types and output parametersWhen I tried it out recently cffi looked like it would be useful for a project I was working on.
- Support `nonzero` annotation for strings and unistrings
- Added `enum` command to define constants and enumerations
- Added `bitmask` annotation for integer parameters
- Added `onerror` annotation for custom error handlers
- Added `disposeonsuccess` annotation to only invalidate pointers on success
- Sample `libzip` wrapper in examples directory
- Miscellaneous bug fixes. See https://github.com/apnadkarni/tcl-cffi/milestone/1?closed=1 for a full list.
Today I was attempting to compile cffi10b4 in windows for a fresh install of tcl8.7a5. Following the guide at Github it was going well until linking the dll. At that point I got this error:
Creating library C:\Users\bmedc\usr\local\src\cffi1.0b4-src\win\Release_AMD64_VC1929\cffi10b4.lib and object C:ptclCffi.obj : error LNK2001: unresolved external symbol mp_clear ...
... \..\HostX64\x64\link.EXE"' : return code '0x460'
A bit of checking showed symbol mp_clear is from libtommath. In tcl8.7a5 source, tommath.lib did contain 'mp_clear', and I assume would be in libtommath.dll (though it had been stripped so I couldn't tell).
Anyway not sure what made it blow up. Any info would be appreciated.
(BTW I did get cffi compiled/installed under Linux with little difficulty. Windows, as usual, is another story...)
On Friday, February 11, 2022 at 10:42:41 PM UTC-8, jrapdx wrote:
Well I decided to see if it worked with tcl 8.6.11, and it did. Compatibility issue with 8.7 isn't a big surprise though I've used 8.7 a fair amount without problems. If you have any thoughts about it I'm still curious about the error with 8.7.
On 2/12/2022 1:02 PM, jrapdx wrote:
On Friday, February 11, 2022 at 10:42:41 PM UTC-8, jrapdx wrote:
Well I decided to see if it worked with tcl 8.6.11, and it did. Compatibility issue with 8.7 isn't a big surprise though I've used 8.7 a fair amount without problems. If you have any thoughts about it I'm still curious about the error with 8.7.
I suspect it has something to do with changes in 8.7 as proposed in
TIP538 - https://core.tcl-lang.org/tips/doc/trunk/tip/538.md - though
not sure exactly what. I'll have to look at it later.
I was under the impression Tcl maintains compatibility between minor versions but perhaps that is only at the script level.
As a short term measure, have you tried building against 8.6 and loading into 8.7? Afaik, that is supposed to work.
/Ashok
As a short term measure, have you tried building against 8.6 and loading into 8.7? Afaik, that is supposed to work.
| Sysop: | Keyop |
|---|---|
| Location: | Huddersfield, West Yorkshire, UK |
| Users: | 716 |
| Nodes: | 16 (2 / 14) |
| Uptime: | 57:00:10 |
| Calls: | 12,117 |
| Files: | 15,010 |
| Messages: | 6,518,672 |