I am trying to use mupdf to create a program (in Qt) that will allow me to list the objects of the document as a list and allow me to select which objects to render / not render. Since Qt is c++, and I am more comfortable with it, I am trying to wrap structures defined in mupdf in C++ classes.
Right now my problem is this - one of the first things you do in mupdf is create a global context, that is passed around to everything, including functions that clean up and delete structures.
I am familiar with creating an object that has an overloaded operator()
, much like:
struct ContextDeleter
{
inline void operator()(fz_context* ctx)
{
fz_drop_context(ctx);
}
};
which I can then hand to unique_ptr
-
std::unique_ptr<fz_context, ContextDeleter> ctxPtr;
What I can't figure out is how to do the same thing with a function like:
fz_drop_page(ctx, page);
ie:
struct PageDeleter
{
inline void operator()(fz_context* ctx, fz_page* pg)
{
fz_drop_page(ctx, pg);
}
}
This is obviously incorrect, but is what I am trying to achieve.
How can I create a deleter for unique_ptr
that includes 2 arguments (in this case the necessary context pointer)? Is there a way for me to make unique_ptr
aware of the context pointer to delete the page (in this example)? Or (one thought I had) do I need to create something that wraps the unique_ptr
so I can hand it the context for deletion later somehow (haven't fully thought it through yet).
I have seen the examples here:
How do I use a custom deleter with a std::unique_ptr member?
and
Wrapping of C-code with a unique_ptr and custom deleter
but I can't figure out how to make them work in my case.
Store the fz_context *
in the deleter, and pass an instance of that deleter to the unique_ptr
that holds the fz_page *
struct PageDeleter
{
explicit PageDeleter(fz_context *ctx)
: ctx(ctx)
{}
void operator()(fz_page* page) const
{
fz_drop_page(ctx, page);
}
fz_context *ctx;
};
Construct the unique_ptr
as
fz_context *ctx = // get the fz_context
fz_page *page = // get the fz_page
PageDeleter page_del(ctx);
std::unique_ptr<fz_page, PageDeleter> pagePtr(page, page_del);
You could wrap all of this in a make_unique_fz_page
function for convenience.