| 
									
										
										
										
											2020-08-18 02:44:43 +08:00
										 |  |  | 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())
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-17 06:03:25 +08:00
										 |  |  | 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
 | 
					
						
							| 
									
										
										
										
											2020-08-18 02:44:43 +08:00
										 |  |  | 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
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. 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.
 |