Search code examples
includeffiforthgforth

How to include a C library in Forth


As default, Forth has only a little amount of working libraries so that everything has to be programmed from scratch. The reason is, that the stackbased Forth virtual machine identifies itself as a slim system.

According to the Gforth manual, it's possible to use existing C libraries and get access to precompiled graphics libraries and game-engines written in C. Before it's possible to include the C library in Forth, it's a good idea to test the library within a normal C project.

I've created a library in C from scratch. It provides an add function and can be called from the main program. The files are compiled and linked and it works fine.

### add.c ###
int add(int a, int b) {
  return a + b;
}
### add.h ###
int add(int, int);

### main.c ###
#include <stdio.h>
#include "add.h"
void main() {
  printf("5 + 7 = %d\n", add(5,7));
}

### compile ###
gcc -c -fPIC add.c
gcc -c main.c
gcc main.o add.o
./a.out
5 + 7 = 12

The plan is to use this precompiled c-library from Forth. The Gforth compiler provides a special keyword for that purpose which connects a Forth program with a C library. Unfortunately, I get an error message saying that the library wasn't found. Even after copying it manually to the Gforth folder, the error message doesn't disappear.

### Forth source code ###
\c #include "add.h"
c-function add add n n -- n
5 7 add .
bye

### Execution ###
gforth "main.fs"
/home/user1/.gforth/libcc-tmp/gforth_c_7F5655710258.c:2:10: fatal error: add.h: No such file or directory
 #include "add.h"
          ^~~~~~~
compilation terminated.

in file included from *OS command line*:-1
b.fs:3: libtool compile failed
5 7 >>>add<<< .
Backtrace:
$7F56556BD988 throw
$7F56556F9798 c(abort")
$7F56556F9F08 compile-wrapper-function

gforth: symbol lookup error: /home/user1/.gforth/libcc-tmp/.libs/gforth_c_7F0593846258.so.0: undefined symbol: add

### Copy missing file and execute again ###
cp add.h /home/user1/.gforth/libcc-tmp/
gforth "main.fs"
gforth: symbol lookup error: /home/user1/.gforth/libcc-tmp/.libs/gforth_c_7F5256AC2258.so.0: undefined symbol: add

What's wrong with the “Forth-to-C interface”?


Solution

  • You have to declare add as a function for export, compile it as a shared library (e.g. libadd.so) and add this library using the add-lib word, see Declaring OS-level libraries.

    s" add" add-lib
    

    NB: prefix 'lib' and suffix '.so' are added automatically.