github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/pybind11/docs/advanced/cast/custom.rst (about) 1 Custom type casters 2 =================== 3 4 In very rare cases, applications may require custom type casters that cannot be 5 expressed using the abstractions provided by pybind11, thus requiring raw 6 Python C API calls. This is fairly advanced usage and should only be pursued by 7 experts who are familiar with the intricacies of Python reference counting. 8 9 The following snippets demonstrate how this works for a very simple ``inty`` 10 type that that should be convertible from Python types that provide a 11 ``__int__(self)`` method. 12 13 .. code-block:: cpp 14 15 struct inty { long long_value; }; 16 17 void print(inty s) { 18 std::cout << s.long_value << std::endl; 19 } 20 21 The following Python snippet demonstrates the intended usage from the Python side: 22 23 .. code-block:: python 24 25 class A: 26 def __int__(self): 27 return 123 28 29 30 from example import print 31 32 print(A()) 33 34 To register the necessary conversion routines, it is necessary to add an 35 instantiation of the ``pybind11::detail::type_caster<T>`` template. 36 Although this is an implementation detail, adding an instantiation of this 37 type is explicitly allowed. 38 39 .. code-block:: cpp 40 41 namespace PYBIND11_NAMESPACE { namespace detail { 42 template <> struct type_caster<inty> { 43 public: 44 /** 45 * This macro establishes the name 'inty' in 46 * function signatures and declares a local variable 47 * 'value' of type inty 48 */ 49 PYBIND11_TYPE_CASTER(inty, const_name("inty")); 50 51 /** 52 * Conversion part 1 (Python->C++): convert a PyObject into a inty 53 * instance or return false upon failure. The second argument 54 * indicates whether implicit conversions should be applied. 55 */ 56 bool load(handle src, bool) { 57 /* Extract PyObject from handle */ 58 PyObject *source = src.ptr(); 59 /* Try converting into a Python integer value */ 60 PyObject *tmp = PyNumber_Long(source); 61 if (!tmp) 62 return false; 63 /* Now try to convert into a C++ int */ 64 value.long_value = PyLong_AsLong(tmp); 65 Py_DECREF(tmp); 66 /* Ensure return code was OK (to avoid out-of-range errors etc) */ 67 return !(value.long_value == -1 && !PyErr_Occurred()); 68 } 69 70 /** 71 * Conversion part 2 (C++ -> Python): convert an inty instance into 72 * a Python object. The second and third arguments are used to 73 * indicate the return value policy and parent object (for 74 * ``return_value_policy::reference_internal``) and are generally 75 * ignored by implicit casters. 76 */ 77 static handle cast(inty src, return_value_policy /* policy */, handle /* parent */) { 78 return PyLong_FromLong(src.long_value); 79 } 80 }; 81 }} // namespace PYBIND11_NAMESPACE::detail 82 83 .. note:: 84 85 A ``type_caster<T>`` defined with ``PYBIND11_TYPE_CASTER(T, ...)`` requires 86 that ``T`` is default-constructible (``value`` is first default constructed 87 and then ``load()`` assigns to it). 88 89 .. warning:: 90 91 When using custom type casters, it's important to declare them consistently 92 in every compilation unit of the Python extension module. Otherwise, 93 undefined behavior can ensue.