Custom type casters =================== In very rare cases, applications may require custom type casters that cannot be expressed using the abstractions provided by pybind11, thus requiring raw Python C API calls. This is fairly advanced usage and should only be pursued by experts who are familiar with the intricacies of Python reference counting. The following snippets demonstrate how this works for a very simple ``inty`` type that that should be convertible from Python types that provide a ``__int__(self)`` method. .. code-block:: cpp struct inty { long long_value; }; void print(inty s) { std::cout << s.long_value << std::endl; } The following Python snippet demonstrates the intended usage from the Python side: .. code-block:: python class A: def __int__(self): return 123 from example import print print(A()) To register the necessary conversion routines, it is necessary to add a partial overload to the ``pybind11::detail::type_caster`` template. Although this is an implementation detail, adding partial overloads to this type is explicitly allowed. .. code-block:: cpp namespace pybind11 { namespace detail { template <> struct type_caster { public: /** * This macro establishes the name 'inty' in * function signatures and declares a local variable * 'value' of type inty */ PYBIND11_TYPE_CASTER(inty, _("inty")); /** * Conversion part 1 (Python->C++): convert a PyObject into a inty * instance or return false upon failure. The second argument * indicates whether implicit conversions should be applied. */ bool load(handle src, bool) { /* Extract PyObject from handle */ PyObject *source = src.ptr(); /* Try converting into a Python integer value */ PyObject *tmp = PyNumber_Long(source); if (!tmp) return false; /* Now try to convert into a C++ int */ value.long_value = PyLong_AsLong(tmp); Py_DECREF(tmp); /* Ensure return code was OK (to avoid out-of-range errors etc) */ return !(value.long_value == -1 && !PyErr_Occurred()); } /** * Conversion part 2 (C++ -> Python): convert an inty instance into * a Python object. The second and third arguments are used to * indicate the return value policy and parent object (for * ``return_value_policy::reference_internal``) and are generally * ignored by implicit casters. */ static handle cast(inty src, return_value_policy /* policy */, handle /* parent */) { return PyLong_FromLong(src.long_value); } }; }} // namespace pybind11::detail