--- gforth/doc/gforth.ds 2007/05/15 20:11:22 1.176 +++ gforth/doc/gforth.ds 2007/06/01 16:27:37 1.177 @@ -11860,11 +11860,9 @@ results in not pushing anything. Note t return value, even if that is often not used in C; in Forth, you have to @code{drop} this return value explicitly if you do not use it. -By default, an integer argument or return value corresponds to a -single cell, and a floating-point argument or return value corresponds -to a Forth float value; the C interface performs the appropriate -conversions where necessary, on a best-effort basis (in some cases, -there may be some loss). +The C interface automatically converts between the C type and the +Forth type as necessary, on a best-effort basis (in some cases, there +may be some loss). As an example, consider the POSIX function @code{lseek()}: @@ -11902,10 +11900,11 @@ compiler, you usually can call such func way is usually not portable between platforms, and sometimes not even between C compilers.}. -Calling functions with a variable number of arguments (e.g., -@code{printf()}) is currently only supported by having you declare one -function-calling word for each argument pattern, and calling the -appropriate word for the desired pattern. +Calling functions with a variable number of arguments (@emph{variadic} +functions, e.g., @code{printf()}) is only supported by having you +declare one function-calling word for each argument pattern, and +calling the appropriate word for the desired pattern. + @node Declaring C Functions, Callbacks, Calling C Functions, C Interface @@ -11914,73 +11913,103 @@ appropriate word for the desired pattern @cindex declaring C functions Before you can call @code{lseek} or @code{dlseek}, you have to declare -it. You have to look up in your system what the concrete type for the -abstract type @code{off_t} is; let's assume it is @code{long}. Then -the declarations for these words are: - -@example -library libc libc.so.6 -libc lseek int long int (long) lseek ( fd noffset whence -- noffset2 ) -libc dlseek int dlong int (dlong) lseek ( fd doffset whence -- doffset2 ) -@end example - -The first line defines a Forth word @code{libc} for accessing the C -functions in the shared library @file{libc.so.6} (the name of the -shared library depends on the library and the OS; this example is the -standard C library (containing most of the standard C and Unix -functions) for GNU/Linux systems since about 1998). - -The next two lines define two Forth words for the same C function -@code{lseek()}; the middle line defines @code{lseek ( n1 n2 n3 -- n -)}, and the last line defines @code{dlseek ( n1 d2 n3 -- d )}. - -As you can see, the declarations are relatively platform-dependent -(e.g., on one platform @code{off_t} may be a @code{long}, whereas on -another platform it may be a @code{long long}; actually, in this case -you can have this difference even on the same platform), while the -resulting function-calling words are platform-independent, and calls -to them are portable. - -At some point in the future this interface will be superseded by a -more convenient one with fewer portability issues. But the resulting -words for calling the C function will still have the same interface, -so you will not need to change the calls. - -Anyway, here are the words for the current interface: - -doc-library -doc-int -doc-dint -doc-uint -doc-udint -doc-long -doc-dlong -doc-ulong -doc-udlong -doc-longlong -doc-dlonglong -doc-ulonglong -doc-udlonglong -doc-ptr -doc-cfloat -doc-cdouble -doc-clongdouble -doc-(int) -doc-(dint) -doc-(uint) -doc-(udint) -doc-(long) -doc-(dlong) -doc-(ulong) -doc-(udlong) -doc-(longlong) -doc-(dlonglong) -doc-(ulonglong) -doc-(udlonglong) -doc-(ptr) -doc-(cfloat) -doc-(cdouble) -doc-(clongdouble) +it. The declaration consists of two parts: + +@table @b + +@item The C part +is the C declaration of the function, or more typically, a C-style +@code{#include} of a file that contains the declaration of the C +function. + +@item The Forth part +declares the Forth types of the parameters and the Forth word name +corresponding to the C function. + +@end table + +For the words @code{lseek} and @code{dlseek} mentioned earlier, the +declarations are: + +@example +\c #define _FILE_OFFSET_BITS 64 +\c #include +\c #include +c-function lseek lseek n n n -- n +c-function dlseek lseek n d n -- d +@end example + +The C part of the declarations is prefixed by @ocde{\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 @code{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 \code{--}, and then +exactly one type for the return value. The possible types are: + +@table @code + +@item n +single-cell integer + +@item a +address (single-cell) + +@item d +double-cell integer + +@item r +floating-point value + +@item func +C function pointer + +@item void +no value (used as return type for void functions) + +@end table + +@cindex variadic C functions + +To deal with variadic C functions, you can declare one Forth word for +every pattern you want to use, e.g.: + +@example +\c #include +c-function printf-nr printf a n r -- n +c-function printf-rn printf a r n -- n +@end example + +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: + +@example +\c #define printf_ull(s,ull) printf(s,(unsigned long long)ull) +c-function printf-ull printf_ull a n -- n +@end example + +Here, instead of calling @code{printf()} directly, we define a macro +that casts (converts) the Forth single-cell (unsigned) integer into a +C @code{unsigned long long} before calling @code{printf()}. + +doc-\c +doc-c-function + +In order to work, this C interface invokes GCC at run-time and uses +dynamic linking. If these features are not availabkle, there are +other, less convenient C interfaces in @file{lib.fs} and +@file{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 @file{lib.fs} interface in @file{lib.fs}. + + + @node Callbacks, Low-Level C Interface Words, Declaring C Functions, C Interface @@ -11988,6 +12017,9 @@ doc-(clongdouble) @cindex Callback functions written in Forth @cindex C function pointers to Forth words +Callbacks are not yet supported by the documented C interface. You +can use the undocumented @file{lib.fs} interface for callbacks. + In some cases you have to pass a function pointer to a C function, i.e., the library wants to call back to your application (and the pointed-to function is called a callback function). You can pass the @@ -11995,13 +12027,8 @@ address of an existing C function (that @pxref{Low-Level C Interface Words}), but if there is no appropriate C function, you probably want to define the function as a Forth word. -!!! @c I don't understand the existing callback interface from the example - anton -doc-callback -doc-callback; -doc-fptr - @c > > Und dann gibt's noch die fptr-Deklaration, die einem @c > > C-Funktionspointer entspricht (Deklaration gleich wie bei @@ -12019,11 +12046,36 @@ doc-fptr @c demselben Prototyp. +@node C interface internals +@subsection How the C interface works + +The documented C interface works by generating a C code out of the +declarations. + +In particular, for every Forth word declared with @code{c-function}, +it generates a wrapper function in C that takes the Forth data from +the Forth stacks, and calls the target C function with these data as +arguments. The C compiler then performs an implicit conversion +between the Forth type from the stack, and the C type for the +parameter, which is given by the C function prototype. After the C +function returns, the return value is likewise implicitly converted to +a Forth type and written back on the stack. + +The @code{\c} lines are literally included in the C code (but without +the @code{\c}), and provide the necessary declarations so that the C +compiler knows the C types and has enough information to perform the +conversion. + +These wrapper functions are eventually compiled and dynamically linked +into Gforth, and then they can be called. + + @node Low-Level C Interface Words, , Callbacks, C Interface @subsection Low-Level C Interface Words doc-open-lib doc-lib-sym +doc-call-c @c ------------------------------------------------------------- @node Assembler and Code Words, Threading Words, C Interface, Words