Version 1 is in SWI-cpp.h; version 2 is in SWI-cpp2.h,
SWI-cpp2.cpp, SWI-cpp2-plx.h, and SWI-cpp2-atommap.h.
The overall structure of the API has been retained - that is, it is a 
thin layer of lightweight classes 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
[]PlTerm and PlTermv 
doesn't cause unexpected implicit conversions.1If 
there is an implicit conversion operator from PlTerm to term_t 
and also to char*, then the []f is overloaded to accept a term_t 
or char* in the code PlTerm t=...; f(t[0]).
Prolog errors 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, an exception type PlFail has 
been added, together with PlCheckFail, to allow more 
compact code by “short circuit” return to Prolog on failure.
A convenience class for creating blobs has been added, so that an existing structure can be converted to a blob with only a few lines of code. More specifically:
SWI-cpp2.cpp has been added, containing the 
implementation of some functions. This is included by default from SWI-cpp2.h 
or can be compiled separately.SWI-Prolog.h, and have the same names with the “PL” replaced 
by “Plx” .2 “Pl” is 
used throughout the SWI-cpp2.h interface, 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 
1.6.4. Many of these wrapper functions are also methods in the PlAtom 
and PlTerm classes, with the arguments changed from
atom_t and term_t to PlAtom and PlTerm 
and in some cases char* and wchar_t* changed 
to std::string and std::wstring. These 
wrappers are available if you include SWI-cpp2.h (they are 
in a separate SWI-cpp2-plx.h file for ease of maintenance).false from a foreign predicate to 
indicate failure, you can throw PlFail(). The convenience 
function PlCheckFail(rc) can 
be used to throw PlFail() if false is returned from 
a function in
SWI-Prolog.h. If the wrapper functions or class methods are 
used, Prolog errors result in a C++ PlException exception.3If 
a “Plx_” wrapper is used to call a SWI-Prolog.h 
function, a Prolog error will have already resulted in throwing PlException;
PlCheckFail(rc) is used to 
additionally throw
PlFail, similar to returning false from the 
top-level of a foreign predicate - Prolog will check for an error and 
call throw/1 if 
appropriate.PlException class is now a subclass of std::exception 
and 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.(char*)t, (int64_t)t,
static_cast<char*>(t)) have been deprecated, replaced 
by “getters” (e.g.,
t.as_string(), t.as_int64_t()).std::string, comparison operators. The PlTerm::as_string() 
method allows specifying the encoding to use whereas the ==char* have been replaced by methods 
that return std::string to ensure that lifetime issues 
don't cause subtle bugs.4If 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::string 
and apply the c_str() method to it. These lifetime 
errors can sometimes be caught by specifying the Gnu C++ or 
Clang options -Wreturn-stack-address or -Wreturn-local-addr 
- as of 2023-04, Clang seems to do a better analysis.char* 
or wchar_t* arguments also accept std::string 
or std::wstring arguments. Where possible, encoding 
information can also be specified.PlString has been renamed to PlTerm_string 
to make it clear that it's a term that contains a Prolog string.PL_...(term_t, ...) methods have been added to PlTerm, 
and PL_...(atom_t, ...) methods have been added to PlAtom. 
Where appropriate, the arguments use PlTerm, PlAtom, 
etc. instead of term_t, atom_t, etc.int for 
true/false now return a C++ bool.term_t, atom_t, 
etc.) have been renamed from handle, ref, etc. 
to
C_.5This is done by 
subclassing from Wrapped<term_t>, Wrapped<atom_t>, 
etc., which define the field C_, standard constructors, the 
methods is_null(), not_null(), reset(), 
reset(v), reset_wrapped(v), plus the constant null. 
This value can be accessed by the unwrap() and unwrap_as_ptr() 
methods. There is also a “friend” function PlUnwrapAsPtr().PlControl::context_unique_ptr<ContextType>() 
has been added, to simplify dynamic memory allocation in 
non-deterministic predicates.PlStringBuffers provides a simpler interface for 
allocating strings on the stack than PL_STRINGS_MARK() and PL_STRINGS_RELEASE(). 
However, this is mostly not needed because most functions now use std::string: 
see section 1.6.9.1.PlStream provides a simpler interface for streams than
PL_get_stream(), PL_acquire_stream(), and PL_release_stream(). 
See section 1.6.9.2.record_t have been added. The
PlRecordExternalCopy class contains the opaque handle, as a 
convenience.control_t has been added and the
PREDICATE_NONDET() has 
been modified to use it.More details on the rationale and how to port from version 1 to version 1 are given in section 1.8 and section 1.9.