Not all functionality of the C-interface is provided, but as
essentially the same thing with automatic type-conversion between the
two, this interface can be freely mixed with the functions defined for
Using this interface rather than the plain C-interface requires a
little more resources. More term-references are wasted (but reclaimed on
return to Prolog or using PlFrame).
Use of some intermediate types (
functor_t etc.) is not
supported in the current interface, causing more hash-table lookups.
This could be fixed, at the price of slighly complicating the interface.
The mechanisms outlined in this document can be used for static linking with the SWI-Prolog kernel using plld(1). In general the C++ linker should be used to deal with the C++ runtime libraries and global constructors. As of SWI-Prolog 3.2.9, PL_register_foreign() can be called before PL_initialise(), which is required to handle the calls from the global PlRegister calls.
The current interface is entirely defined in the
using inlined code. This approach has a few advantages: as no C++ code
is in the Prolog kernel, different C++ compilers with different
name-mangling schemas can cooperate smoothly.
Also, changes to the header file have no consequences to binary compatibility with the SWI-Prolog kernel. This makes it possible to have different versions of the header file with few compatibility consequences. If the interface stabilises we will consider options to share more code.
Currently, the following limitations are recognised:
- Predicate naming
Using the PREDICATE() macro, only predicates with a name that is valid as part of a C-symbol can be defined. Notably this makes the definition of predicates with names consisting of symbol characters impossible.
- Non-deterministic predicates
The current interface does not provide for foreign-defined non-deterministic predicates. It would not be hard to add this.