| 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<T>`` 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<inty> { |
| 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 |
| |
| .. warning:: |
| |
| When using custom type casters, it's important to declare them consistently |
| in every compilation unit of the Python extension module. Otherwise, |
| undefined behavior can ensue. |