|Did you know ...||Search Documentation:|
|Summary of changes between Versions 1 and 2|
Version 1 is in
SWI-cpp.h; version 2 is in
The overall structure of the API has been retained - that is, it is a
thin layer on top of the interface provided by
SWI-Prolog.h. Based on experience with the API, most of the
conversion operators and some of the comparison operators have been
removed or deprecated, and replaced by "getter" methods. The overloaded
constructors have been replaced by subclasses for the various types.
Some changes were also made to ensure that the
doesn't cause unexpected implicit conversions.
2If there is an implicit
conversion operator from
char*, then the
operator is ambiguous if
f is overloaded to accept a
char* in the code
PlTerm t=...; f(t)
Prolog exceptions are now converted to C++ exceptions (which contain
the exception term rather being a subclass of
PlTerm as in
version 1), where they can be caught and thrown using the usual C++
mechanisms; and the subclasses that create exceptions have been changed
to functions. In addition, a
PlFail has been added, to
allow "short circuit" return to Prolog on failure.
SWI-cpp2.cpphas been added, containing the implementation of some functions that are too long to inline. The user must either
#include <SWI-cpp2.cpp>or compile it separately and link it with the other foreign function code.
SWI-Prolog.h, and have the same names with the “PL'' replaced by “Plx''.3 “Pl'' is used throughout the
SWI-cpp2.hinterface, and the “x'' is for “eXtended with eXception handling.'' Where appropriate, these check return codes and throw a C++ exception (created from the Prolog error). See section 2.4.4 Many of these wrapper functions have been added to the
PlTermclasses, with the arguments changed from
PlTerm. These wrappers are available if you include
SWI-cpp2.h(they are in a separate
SWI-cpp2-plx.hfile for ease of maintenance).
falsefrom a foreign predicate to indicate failure, you can use
throw PlFail(). The convenience function PlCheckFail(rc) can be used to throw PlFail() if
falseis returned from a function in
SWI-Prolog.h. If the wrapper functions or class methods are used, Prolog errors result in a C++
PlExceptionexception.4If a “Plx_'' wrapper is used to call a
SWI-Prolog.hfunction, a Prolog error will have already resulted in throwing
PlException;‘cfuncrefPlCheckFailrc is used to additionally throw
PlFail, similar to returning
falsefrom the top-level of a foreign predicate.
PlExceptionclass is a subclass of
std::excxeptionand encapsulates a Prolog error. Prolog errors are converted into
throw PlException(...). If the user code does not catch the
PlException, the PREDICATE() macro converts the error to a Prolog error upon return to the Prolog caller.
(int64_t)t) have been deprecated, replaced by "getters" (e.g.,
(char*)tis a C-style cast; C++'s preferred form is more verbose:
std::string, comparison operators. The as_string() method allows specifying the encoding to use whereas the
and similar operators do not allow for this.
char*have been replaced by methods that return
std::stringto ensure that lifetime issues don't cause subtle bugs.6If you want to return a
char*from a function, you should not do
return t.as_string().c_str()because that will return a pointer to local or stack memory. Instead, you should change your interface to return a
std::stringand apply the
c_str()method to it. These lifetime errors can sometimes be caught by specifying the Gnu C++ or Clang options
-Wreturn-local-addr- as of 2023-04, Clang seems to do a better analysis.
char*arguments also accept
std::wstringarguments. Where possible, encoding information can also be specified.
PlStringhas been renamed to
PlTerm_stringto make it clear that it's a term that contains a Prolog string.
PL_...(term_t, ...)methods have been added to
PL_...(atom_t, ...)methods have been added to
PlAtom. Where appopriate, the arguments use
PlAtom, etc. instead of
std::wstringare now supported in most places where
intfor true/false now return a C++
atom_t, etc.) have been renamed from
ref, etc. to
C_.7This is done by subclassing from
Wrapped<atom_t>, etc., which define the field
C_, standard constructors, the methods is_null(), not_null(), reset(), and reset(v), plus the constant
PlForeignContextPtr<ContextType>has been added, to simplify dynamic memory allocation in non-deterministic predicates.
PlStringBuffersprovides a simpler interface for allocating strings on the stack than PL_STRINGS_MARK() and PL_STRINGS_RELEASE().
record_thave been added. The
PlRecordExternalCopyclass contains the opaque handle, as a convenience.
control_thas been added and the PREDICATE_NONDET() has been modified to use it.
More details are given in section 2.6 and section 2.7.