Next: Calling C function pointers, Previous: Calling C Functions, Up: C Interface
Before you can call lseek
or dlseek
, you have to declare
it. The declaration consists of two parts:
#include
of a file that contains the declaration of
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
a
d
r
func
void
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. In such cases you can perform the conversion explicitly on the C level, e.g., as follows:
\c #define printfll(s,ll) printf(s,(long long)ll) c-function printfll printfll a n -- n
Here, instead of calling printf()
directly, we define a macro
that casts (converts) the Forth single-cell integer into a
C long long
before calling printf()
.
\c
"rest-of-line" – gforth “backslash-c”
One line of C declarations for the C interface
c-function
"forth-name" "c-name" "{type}" "–" "type" – gforth “c-function”
Define a Forth word forth-name. Forth-name has the
specified stack effect and calls the C function 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.