Search code examples
pythonc++pybind11

pybind11 how to cast double pointer argument implicitly to long value?


I'm trying to expose c++ library with classes that have function members that receives double pointer argument (for initialization) to python via pybind11.

For example:

class IInitializer{
   virtual bool CreateTexture(ITexture **out_pTex, UINT Width, UINT Height) = 0;
}

I know that pybind11 has no support out-of-the-box for double pointer argument.

in the python side I would like to receive the out_pTex as long number or opaque pointer. I do not need to do anything with this pointer on the python side just pass it as handle to other c++ functions.

I tried to create custom type caster like this:

template <> struct type_caster<ITexture*> : public type_caster_base<ITexture*>
{
using base = type_caster_base<ITexture*>;
public:
PYBIND11_TYPE_CASTER(ITexture*, const_name("ITexture*"));
bool load(handle src, bool) {
    value = reinterpret_cast<ITexture*>(PyLong_AsVoidPtr(src.ptr()));
    return true;
}
static handle cast(ITexture* src, return_value_policy, handle) {
return PyLong_FromVoidPtr((void*)src);
}
};

but I keep getting compilation errors like:

no known conversion for argument 1 from ‘pybind11::detail::type_caster_base<ITexture>::cast_op_type<ITexture**&&> {aka ITexture*}’ to ‘ITexture**’

Anyone has a suggestion how to expose double pointer to some class (as opaque or long number) to python?


Solution

  • I would write the glue code into a lambda:

    IInitializerWrap.def("CreateTexture", [](const IInitializer& self, UINT Width, UINT Height) {
      ITexture* rv;
      self.CreateTexture(&rv, Width, Height);
      return rv; // Or reinterpret_cast if you prefer to.
    });