Home Contents Index Summary Previous Next

5.9 Notes on Using Foreign Code

5.9.1 Memory Allocation

SWI-Prolog's memory allocation is based on the malloc(3) library routines. Foreign applications can safely use malloc(3), realloc(3) and free(3). Memory allocation using brk(2) or sbrk(2) is not allowed as these calls conflict with malloc(3).

5.9.2 Debugging Foreign Code

Statically linked foreign code or embedded systems can be debugged normally. Most modern environments provide debugging tools for dynamically loaded shared objects or dynamic load libraries. The following example traces the code of lowercase using gdb(1) in a Unix environment.

% gcc -I/usr/local/lib/pl-2.2.0/include -fpic -c -g lowercase.c % gcc -shared -o lowercase.so lowercase.o % gdb pl (gdb) r Welcome to SWI-Prolog (Version \plversion) Copyright (c) 1993-1996 University of Amsterdam. All rights reserved. For help, use ?- help(Topic). or ?- apropos(Word). ?- load_foreign_library(lowercase). <type Control-C> (gdb) shared % loads symbols for shared objects (gdb) break pl_lowercase (gdb) continue ?- lowercase('HELLO', X).

5.9.3 Name Conflicts in C modules

In the current version of the system all public C functions of SWI-Prolog are in the symbol table. This can lead to name clashes with foreign code. Someday I should write a program to strip all these symbols from the symbol table (why does Unix not have that?). For now I can only suggest to give your function another name. You can do this using the C preprocessor. If---for example---your foreign package uses a function warning(), which happens to exist in SWI-Prolog as well, the following macro should fix the problem.

#define warning warning_

Note that shared libraries do not have this problem as the shared library loader will only look for symbols in the main executable for symbols that are not defined in the library itself.

5.9.4 Compatibility of the Foreign Interface

The term-reference mechanism was first used by Quintus Prolog version 3. SICStus Prolog version 3 is strongly based on the Quintus interface. The described SWI-Prolog interface is similar to using the Quintus or SICStus interfaces, defining all foreign-predicate arguments of type +term. SWI-Prolog explicitly uses type functor_t, while Quintus and SICStus uses <name> and <arity>. As the names of the functions differ from Prolog to Prolog, a simple macro layer dealing with the names can also deal with this detail. For example:

#define QP_put_functor(t, n, a) PL_put_functor(t, PL_new_functor(n, a))

The PL_unify_*() functions are lacking from the Quintus and SICStus interface. They can easily be emulated or the put/unify approach should be used to write compatible code.

The PL_open_foreign_frame()/PL_close_foreign_frame() combination is lacking from both other Prologs. SICStus has PL_new_term_refs(0), followed by PL_reset_term_refs() that allows for discarding term references.

The Prolog interface for the graphical user interface package XPCE shares about 90% of the code using a simple macro layer to deal with different naming and calling conventions of the interfaces.