|Did you know ...||Search Documentation:|
|The life of a PlBlob|
In this section, the blob is of type
MyBlob, a subclass
A blob is typically created by calling a predicate that does the following:
auto ref = std::unique_ptr<PlBlob>(new MyBlob>(...))(std::make_unique() can't be used because it returns type
std::unique_ptr<MyBlob>but PlTerm::unify_blob() requires a
std::unique_ptr<PlBlob>and C++'s type inferencing can't figure out that this is a covariant type).
ref.release()to pass ownership to the Prolog blob. If you wish to use std::make_unique<MyBlob>(), you could instead do:
auto ref = std::make_unique<MyBlob>(...); ... // code that accesses fields in *ref std::unique_ptr<PlBlob> refb(ref.release()); // transfer ownership of ptr // from here on, can't access fields in *ref return A2.unify_blob(refb);
At this point, the blob is owned by Prolog and will be freed by its atom garbage collector, which will call the blob's destructor.
Whenever a predicate is called with the blob as an argument (e.g., as A1),
the blob can be accessed by
Within a method, the Prolog blob can be accessed as a term (e.g., for
constructing an error term) using the method MyBlob::symbol_term(). This
field is initialized by the call to PlTerm::unify_blob(); if
MyBlob::symbol_term() is called before a successful call to
PlTerm::unify_blob(), MyBlob::symbol_term() returns a
When the atom garbage collector runs, it frees the blob by first
calling the release() callback, which does
calls the destructor MyBlob:: MyBlob(). Note that C++ destructors
are not supposed to raise exception; they also should not cause a Prolog
error, which could cause deadlock unless the real work is done in
Often it is desired to release the resources before the garbage collector runs. To do this, the programmer can provide a "close" predicate which is the inverse of the "open" predicate that created the blob. This typically has the same logic as the destructor, except that it can raise a Prolog error.