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.