Skip to content

Commit 48ce072

Browse files
committed
added docs for custom type casters (fixes #298)
1 parent 146397e commit 48ce072

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

docs/advanced.rst

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,3 +1937,85 @@ is always ``none``).
19371937
19381938
// Evaluate the statements in an separate Python file on disk
19391939
py::eval_file("script.py", scope);
1940+
1941+
Development of custom type casters
1942+
==================================
1943+
1944+
In very rare cases, applications may require custom type casters that cannot be
1945+
expressed using the abstractions provided by pybind11, thus requiring raw
1946+
Python C API calls. This is fairly advanced usage and should only be pursued by
1947+
experts who are familiar with the intricacies of Python reference counting.
1948+
1949+
The following snippets demonstrate how this works for a very simple ``inty``
1950+
type that that should be convertible from Python types that provide a
1951+
``__int__(self)`` method.
1952+
1953+
.. code-block:: cpp
1954+
1955+
struct inty { long long_value; };
1956+
1957+
void print(inty s) {
1958+
std::cout << s.long_value << std::endl;
1959+
}
1960+
1961+
The following Python snippet demonstrates the intended usage from the Python side:
1962+
1963+
.. code-block:: python
1964+
1965+
class A:
1966+
def __int__(self):
1967+
return 123
1968+
1969+
from example import print
1970+
print(A())
1971+
1972+
To register the necessary conversion routines, it is necessary to add
1973+
a partial overload to the ``pybind11::detail::type_caster<T>`` template.
1974+
Although this is an implementation detail, adding partial overloads to this
1975+
type is explicitly allowed.
1976+
1977+
.. code-block:: cpp
1978+
1979+
namespace pybind11 {
1980+
namespace detail {
1981+
template <> struct type_caster<inty> {
1982+
public:
1983+
/**
1984+
* This macro establishes the name 'inty' in
1985+
* function signatures and declares a local variable
1986+
* 'value' of type inty
1987+
*/
1988+
PYBIND11_TYPE_CASTER(inty, _("inty"));
1989+
1990+
/**
1991+
* Conversion part 1 (Python->C++): convert a PyObject into a inty
1992+
* instance or return false upon failure. The second argument
1993+
* indicates whether implicit conversions should be applied.
1994+
*/
1995+
bool load(handle src, bool) {
1996+
/* Extract PyObject from handle */
1997+
PyObject *source = src.ptr();
1998+
/* Try converting into a Python integer value */
1999+
PyObject *tmp = PyNumber_Long(source);
2000+
if (!tmp)
2001+
return false;
2002+
/* Now try to convert into a C++ int */
2003+
value.long_value = PyLong_AsLong(tmp);
2004+
Py_DECREF(tmp);
2005+
/* Ensure return code was OK (to avoid out-of-range errors etc) */
2006+
return !(value.long_value == -1 && !PyErr_Occurred());
2007+
}
2008+
2009+
/**
2010+
* Conversion part 2 (C++ -> Python): convert an inty instance into
2011+
* a Python object. The second and third arguments are used to
2012+
* indicate the return value policy and parent object (for
2013+
* ``return_value_policy::reference_internal``) and are generally
2014+
* ignored by implicit casters.
2015+
*/
2016+
static handle cast(inty src, return_value_policy /* policy */, handle /* parent */) {
2017+
return PyLong_FromLong(src.long_value);
2018+
}
2019+
};
2020+
}
2021+
};

0 commit comments

Comments
 (0)