You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							85 lines
						
					
					
						
							3.1 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							85 lines
						
					
					
						
							3.1 KiB
						
					
					
				| 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.
 |