PL_blob_t structure with the wrapper functions and flags 
set to PL_BLOB_NOCOPY. It should be declared outside the PlBlob 
class and should not be marked const - otherwise, a runtime 
error can occur.20The cause of the 
runtime error is not clear, but possibly has to do with the order of 
initializing globals, which is unspecified for C++.
MyBlob struct is a subclass of PlBlob. 
See below for a discussion of the default behaviors.
MyBlob contains a pointer to a MyConnection 
object and keeps a copy of the connection's name. The MyConnection 
object is handled by a std::unique_ptr smart pointer, so 
that it is automatically freed when the MyBlob object is 
freed.
PlBlob 
constructor.
MyBlob class must not provide a copy or move 
constructor, nor an assignment operator (PlBlob has these as
delete, so if you try to use one of these, you will get 
a compile-time error).
PlBlob’s constructor sets blob_t_ to 
a pointer to the my_blob definition. This is used for 
run-time consistency checking by the various callback functions and for 
constructing error terms (see PlBlob::symbol_term()).
PlBlob’s acquire() is called by PlBlobV<MyBlob>::acquire() 
and fills in the symbol_ field. MyBlob must 
not override this - it is not a virtual method. The symbol_ 
field can be accessed by PlBlob::symbol_term().
MyConnection object. If this fails, an exception is thrown. 
The constructor then calls MyConnection::open() and throws an 
exception if that fails. (The code would be similar if instead the 
constructor for MyConnection also did an open and threw an 
exception on failure.)
PL_BLOB_SIZE is boilerplate that defines a
blob_size_() method that is used when the blob is created.
PlUnknownError("..."), 
that will try to create a Prolog term, which will crash because the 
environment for creating terms is not available. Because 
there is no mechanism for reporting an error, the destructor prints a 
message on failure (calling
PL_warning() would cause a crash).
PlBlob::close() calls MyConnection::close() and then 
frees the object. Error handling is left to the caller because of the 
possibility that this is called in the context of garbage collection. It 
is not necessary to free the MyConnection object here - if 
it is not freed, the
std::unique_ptr<MyConnection>’s 
destructor would free it.
0 (``equal” ).
The _b_data argument is of type const PlBlob* 
- this is cast to const MyBlob* using a
static_cast. This is safe because Prolog guarantees that 
PlBlobV<PlBlob>::compare() will only be called 
if both blobs are of the same type.
The flags argument is the same as given to PlBlobV<PlBlob>::write(), 
which is a bitwise or of zero or more of the PL_WRT_* 
flags that were passed in to the caling PL_write_term() (defined 
in SWI-Prolog.h). The
flags do not have the PL_WRT_NEWLINE bit set, so 
it is safe to call PlTerm::write() and there is no need for 
writing a trailing newline.
If anything in PlBlob::write_fields() throws a C++ exception, it will be caught by the calling PlBlobV<PlBlob>::write() and handled appropriately.
std::unique_ptr<PlBlob>() creates a 
MyBlob that is deleted when it goes out of scope. If an exception occurs 
between the creation of the blob or if the call to unify_blob() 
fails, the pointer will be automatically freed (and the
MyBlob destructor will be called).
PlTerm::unify_blob() 
is called with a pointer to a
std::unique_ptr, which takes ownership of the object by 
calling std::unique_ptr<PlBlob>::release() and 
passes the pointer to Prolog, which then owns it. This also sets ref 
to nullptr, so any attempt to use ref after a 
call to PlTerm::unify_blob() 
will be an error.
If you wish to create a MyBlob object instead of a
PlBlob object, a slightly different form is used:
auto ref = std::make_unique<MyBlob>(...);
  ...
std::unique_ptr<PlBlob> refb(ref.release());
PlCheckFail(A2.unify_blob(&refb));
return true;
      
MyBlob pointer using the 
PlBlobV<MyBlob>::cast_ex() function, which will 
throw a
type_error if the argument isn't a blob of the expected 
type.