A work-in-progress Fortran 2018 ISO_C_BINDING interface library for interoperability with Tcl/Tk 8.6. This library allows you
- to embed Tcl into Fortran,
- to create Tcl extensions in Fortran (with Tcl Stubs),
- to access (a subset of) the Tcl/Tk C API from Fortran,
- to use Tcl as an evaluatable configuration file format, and
- to add graphical user interfaces to Fortran programs.
There are some smaller differences to the original API:
- Procedure names have been converted from camel case to snake case (for
example,
tcl_eval_ex()in Fortran instead ofTcl_EvalEx()in C). - Character strings passed to library procedures do not have to be null-terminated, as this step is done by Fortran wrappers.
- Types are converted to their Fortran counter-parts (such as
logicalinstead ofc_intfor boolean values). - Some procedure arguments have been made optional to avoid passing of
c_null_ptr,c_null_funptr, and0. - The interfaces called by the wrapper procedures contain a trailing underscore
_in their name (for example, wrappertcl_eval()appends a null character to the second argument, then calls Fortran interfacetcl_eval_()). - Functions and routines exposed to Tcl must have the
bind(c)attribute.
See COVERAGE for a table of the bound procedures.
| Library | Description |
|---|---|
libftcl86.a |
Bindings to Tcl (libtcl86) |
libftclstub86.a |
Bindings to Tcl Stubs for extensions in Fortran (libtclstub86) |
libftk86.a |
Bindings to Tk (libtk86) |
Tcl 8.6 and Tk 8.6 with development headers have to be present. On FreeBSD, install the packages with:
# pkg install lang/tcl86 x11-toolkits/tk86
You will also need a Fortran 2018 and a C compiler. Then, execute the provided
Makefile to build the static Fortran interface libraries libftcl86.a,
libftclstub86.a, and libftk86.a:
$ make
By default, gcc and gfortran are used for compilation, but you can override
the settings:
$ make CC=icc FC=ifort
Furthermore, it is possible to build a single static library libfortran-tcl86.a
with fpm:
$ fpm build --profile=release --c-flag="`pkg-config --cflags tcl86`"
The include and library search paths in --c-flags have to point to the correct
directories.
Linking depends on whether Fortran is called from Tcl or Tcl from Fortran. To
build a Fortran program in example.f90 that invokes the Tcl interpreter, link
against libftcl86.a -ltcl86:
$ gfortran -I/usr/local/include/tcl8.6/ -L/usr/local/lib/tcl8.6/ \
-o example example.f90 libftcl86.a -ltcl86
$ ./example
The include and library search paths as well as the name of the Tcl 8.6 library
itself may have to be changed depending on your operating system (-ltcl8.6
instead of -ltcl86 on Linux). Tcl/Tk can either be linked statically
(libtcl86.a, libtk86.a) or dynamically (-ltcl86, -ltk86).
To create a shared library libexample.so with Tcl extensions written in
Fortran, run:
$ gfortran -DUSE_TCL_STUBS -fPIC -shared -o libexample.so `pkg-config --cflags tcl86` \
example.f90 libftcl86.a libftclstub86.a `pkg-config --libs tcl86`
To access the Tk toolkit from Fortran, link against libftk86.a libftcl86.a -ltk86 -ltcl86 (or, use pkg-config):
$ gfortran -DUSE_TK_STUBS `pkg-config --cflags tk86` \
-o example example.f90 libftk86.a libftcl86.a `pkg-config --libs tk86`
$ ./example
The following basic example just invokes the Tcl interpreter from Fortran to evaluate a character string:
! example.f90
program main
use, intrinsic :: iso_c_binding, only: c_associated, c_ptr
use :: tcl
implicit none (type, external)
integer :: rc
type(c_ptr) :: interp
! Create Tcl interpreter.
interp = tcl_create_interp()
if (.not. c_associated(interp)) stop 'Error: Tcl_CreateInterp() failed'
! Evaluate string as Tcl command.
rc = tcl_eval_ex(interp, 'puts "Hello, from Tcl!"')
if (rc /= TCL_OK) print '("Error: Tcl_EvalEx() failed")'
! Delete Tcl interpreter.
call tcl_delete_interp(interp)
end program mainCompile and link the example with:
$ gfortran `pkg-config --cflags tcl86` -o example.f90 libftcl86.a `pkg-config --libs tcl86`
$ ./example
Hello, from Tcl!
The following example programs are provided:
- config – Uses Tcl as a configuration file format (run
config). - dict – Shows dictionary access (run
dict). - eval – Evaluates a script in the Tcl interpreter (run
eval). - fs – Tests Tcl file system API procedures (run
fs). - library – Creates a Tcl extension
helloinside a shared library (runscript.tcl). - link – Demonstrates shared access to a variable between Tcl and Fortran (run
link). - namespace – Creates a Tcl extension
::fortran::hello(with namespace) inside a shared library (runscript.tcl). - re2c – Shows a Tk window to convert temperature values by calling an extension written in Fortran (run
re2c).
To build the examples, run:
$ make examples
Change to the directory of an example before executing it.
ISC