Before you can call lseek
or dlseek
, you have to declare
it. The declaration consists of two parts:
is the C declaration of the function, or more typically and portably,
a C-style #include
of a file that contains the declaration of
the C function.
declares the Forth types of the parameters and the Forth word name corresponding to the C function.
For the words lseek
and dlseek
mentioned earlier, the
declarations are:
\c #define _FILE_OFFSET_BITS 64 \c #include <sys/types.h> \c #include <unistd.h> c-function lseek lseek n n n -- n c-function dlseek lseek n d n -- d
The C part of the declarations is prefixed by \c
, and the rest
of the line is ordinary C code. You can use as many lines of C
declarations as you like, and they are visible for all further
function declarations.
The Forth part declares each interface word with c-function
,
followed by the Forth name of the word, the C name of the called
function, and the stack effect of the word. The stack effect contains
an arbitrary number of types of parameters, then --
, and then
exactly one type for the return value. The possible types are:
n
single-cell integer
a
address (single-cell)
d
double-cell integer
r
floating-point value
func
C function pointer
void
no value (used as return type for void functions)
To deal with variadic C functions, you can declare one Forth word for every pattern you want to use, e.g.:
\c #include <stdio.h> c-function printf-nr printf a n r -- n c-function printf-rn printf a r n -- n
Note that with C functions declared as variadic (or if you don’t provide a prototype), the C interface has no C type to convert to, so no automatic conversion happens, which may lead to portability problems in some cases. You can add the C type cast in curly braces after the Forth type. This also allows to pass e.g. structs to C functions, which in Forth cannot live on the stack.
c-function printfll printf a n{(long long)} -- n c-function pass-struct pass_struct a{*(struct foo *)} -- n
This typecasting is not available to return values, as C does not allow typecasts for lvalues.
\c
( "rest-of-line" – ) gforth-0.7 “backslash-c”
One line of C declarations for the C interface
c-function
( "forth-name" "c-name" "{type}" "—" "type" – ) gforth-0.7 “c-function”
Define a Forth word forth-name. Forth-name has the
specified stack effect and calls the C function c-name
.
c-value
( "forth-name" "c-name" "—" "type" – ) gforth-1.0 “c-value”
Define a Forth word forth-name. Forth-name has the
specified stack effect and gives the C value of c-name
.
c-variable
( "forth-name" "c-name" – ) gforth-1.0 “c-variable”
Define a Forth word forth-name. Forth-name returns the
address of c-name
.
In order to work, this C interface invokes GCC at run-time and uses dynamic linking. If these features are not available, there are other, less convenient and less portable C interfaces in lib.fs and oldlib.fs. These interfaces are mostly undocumented and mostly incompatible with each other and with the documented C interface; you can find some examples for the lib.fs interface in lib.fs.