| 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 an |
| instantiation of the ``pybind11::detail::type_caster<T>`` template. |
| Although this is an implementation detail, adding an instantiation of this |
| type is explicitly allowed. |
|
|
| .. code-block:: cpp |
|
|
| namespace PYBIND11_NAMESPACE { namespace detail { |
| template <> struct type_caster<inty> { |
| public: |
| |
| |
| |
| |
| |
| PYBIND11_TYPE_CASTER(inty, const_name("inty")); |
|
|
| |
| |
| |
| |
| |
| bool load(handle src, bool) { |
| |
| PyObject *source = src.ptr(); |
| |
| PyObject *tmp = PyNumber_Long(source); |
| if (!tmp) |
| return false; |
| |
| value.long_value = PyLong_AsLong(tmp); |
| Py_DECREF(tmp); |
| |
| return !(value.long_value == -1 && !PyErr_Occurred()); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| static handle cast(inty src, return_value_policy , handle ) { |
| return PyLong_FromLong(src.long_value); |
| } |
| }; |
| }} |
|
|
| .. note:: |
| |
| A ``type_caster<T>`` defined with ``PYBIND11_TYPE_CASTER(T, ...)`` requires |
| that ``T`` is default-constructible (``value`` is first default constructed |
| and then ``load()`` assigns to it). |
|
|
| .. 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. |
| |