mirror of
https://github.com/pybind/pybind11.git
synced 2025-02-16 13:47:53 +00:00
return value policy clarifications
This commit is contained in:
parent
1f66a58427
commit
fb6aed2157
@ -507,8 +507,59 @@ functions. The default policy is :enum:`return_value_policy::automatic`.
|
|||||||
| | policy described next. |
|
| | policy described next. |
|
||||||
+--------------------------------------------------+----------------------------------------------------------------------------+
|
+--------------------------------------------------+----------------------------------------------------------------------------+
|
||||||
|
|
||||||
The following example snippet shows a use case of the
|
.. warning::
|
||||||
:enum:`return_value_policy::reference_internal` policy.
|
|
||||||
|
Code with invalid call policies might access unitialized memory or free
|
||||||
|
data structures multiple times, which can lead to hard-to-debug
|
||||||
|
non-determinism and segmentation faults, hence it is worth spending the
|
||||||
|
time to understand all the different options in the table above.
|
||||||
|
|
||||||
|
One important aspect regarding the above policies is that they only apply to
|
||||||
|
instances which pybind11 has *not* seen before, in which case the policy
|
||||||
|
clarifies essential questions about the return value's lifetime and ownership.
|
||||||
|
|
||||||
|
When pybind11 knows the instance already (as identified via its address in
|
||||||
|
memory), it will return the existing Python object wrapper rather than creating
|
||||||
|
a copy. This means that functions which merely cast a reference (or pointer)
|
||||||
|
into a different type don't do what one would expect:
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
A &func(B &value) { return (A&) value; }
|
||||||
|
|
||||||
|
The wrapped version of this function will return the original ``B`` instance.
|
||||||
|
To force a cast, the argument should be returned by value.
|
||||||
|
|
||||||
|
More common (and equally problematic) are cases where methods (e.g. getters)
|
||||||
|
return a pointer or reference to the first attribute of a class.
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
:emphasize-lines: 3, 13
|
||||||
|
|
||||||
|
class Example {
|
||||||
|
public:
|
||||||
|
Internal &get_internal() { return internal; }
|
||||||
|
private:
|
||||||
|
Internal internal;
|
||||||
|
};
|
||||||
|
|
||||||
|
PYBIND11_PLUGIN(example) {
|
||||||
|
py::module m("example", "pybind11 example plugin");
|
||||||
|
|
||||||
|
py::class_<Example>(m, "Example")
|
||||||
|
.def(py::init<>())
|
||||||
|
.def("get_internal", &Example::get_internal); /* Note: don't do this! */
|
||||||
|
|
||||||
|
return m.ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
As in the above casting example, the instance and its attribute will be located
|
||||||
|
at the same address in memory, which pybind11 will recongnize and return the
|
||||||
|
parent instance instead of creating a new Python object that represents the
|
||||||
|
attribute. The special :enum:`return_value_policy::reference_internal` policy
|
||||||
|
should be used in this case: it disables the same-address optimization and
|
||||||
|
ensures that pybind11 returns a reference.
|
||||||
|
The following example snippet shows the correct usage:
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
|
|
||||||
@ -530,20 +581,7 @@ The following example snippet shows a use case of the
|
|||||||
return m.ptr();
|
return m.ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
Code with invalid call policies might access unitialized memory or free
|
|
||||||
data structures multiple times, which can lead to hard-to-debug
|
|
||||||
non-determinism and segmentation faults, hence it is worth spending the
|
|
||||||
time to understand all the different options in the table above.
|
|
||||||
|
|
||||||
It is worth highlighting one common issue where a method (e.g. a getter)
|
|
||||||
returns a reference (or pointer) to the first attribute of a class. In this
|
|
||||||
case, the class and attribute will be located at the same address in
|
|
||||||
memory, which pybind11 will recongnize and return the parent instance
|
|
||||||
instead of creating a new Python object that represents the attribute.
|
|
||||||
Here, the :enum:`return_value_policy::reference_internal` policy should be
|
|
||||||
used rather than relying on the automatic one.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user