Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pybind11
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
pybind11
Commits
0871228f
Commit
0871228f
authored
Apr 22, 2016
by
Wenzel Jakob
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
opaque<> clarifications
parent
5a292427
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
78 additions
and
14 deletions
+78
-14
docs/advanced.rst
+38
-6
example/example14.cpp
+21
-3
example/example14.py
+15
-0
example/example14.ref
+4
-5
No files found.
docs/advanced.rst
View file @
0871228f
...
...
@@ -1145,8 +1145,8 @@ linked lists, hash tables, etc. This even works in a recursive manner, for
instance to deal with lists of hash maps of pairs of elementary and custom
types, etc.
A fundamental limitation of this approach is that the internal conversion
between Python and C++ types involve
s
a copy operation that prevents
However, a fundamental limitation of this approach is that internal conversions
between Python and C++ types involve a copy operation that prevents
pass-by-reference semantics. What does this mean?
Suppose we bind the following function
...
...
@@ -1167,10 +1167,41 @@ and call it as follows from Python:
[5, 6]
As you can see, when passing STL data structures by reference, modifications
are not propagated back the Python side. To deal with situations where this
desirable, pybind11 contains a simple template wrapper class named ``opaque<T>``.
are not propagated back the Python side. A similar situation arises when
exposing STL data structures using the ``def_readwrite`` or ``def_readonly``
functions:
``opaque<T>`` disables the underlying template machinery for
.. code-block:: cpp
/* ... definition ... */
class MyClass {
std::vector<int> contents;
};
/* ... binding code ... */
py::class_<MyClass>(m, "MyClass")
.def(py::init<>)
.def_readwrite("contents", &MyClass::contents);
In this case, properties can be read and written in their entirety. However, an
``append`` operaton involving such a list type has no effect:
.. code-block:: python
>>> m = MyClass()
>>> m.contents = [5, 6]
>>> print(m.contents)
[5, 6]
>>> m.contents.append(7)
>>> print(m.contents)
[5, 6]
To deal with both of the above situations, pybind11 contains a simple template
wrapper class named ``opaque<T>``.
``opaque<T>`` disables pybind11's template-based conversion machinery for
``T`` and can be used to treat STL types as opaque objects, whose contents are
never inspected or extracted (thus, they can be passed by reference).
The downside of this approach is that it the binding code becomes a bit more
...
...
@@ -1186,7 +1217,8 @@ set of admissible operations.
.. seealso::
The file :file:`example/example14.cpp` contains a complete example that
demonstrates how to create opaque types using pybind11 in more detail.
demonstrates how to create and expose opaque types using pybind11 in more
detail.
Pickling support
================
...
...
example/example14.cpp
View file @
0871228f
...
...
@@ -13,6 +13,11 @@
typedef
std
::
vector
<
std
::
string
>
StringList
;
class
ClassWithSTLVecProperty
{
public
:
StringList
stringList
;
};
void
init_ex14
(
py
::
module
&
m
)
{
py
::
class_
<
py
::
opaque
<
StringList
>>
(
m
,
"StringList"
)
.
def
(
py
::
init
<>
())
...
...
@@ -20,11 +25,24 @@ void init_ex14(py::module &m) {
.
def
(
"pop_back"
,
[](
py
::
opaque
<
StringList
>
&
l
)
{
l
->
pop_back
();
})
.
def
(
"back"
,
[](
py
::
opaque
<
StringList
>
&
l
)
{
return
l
->
back
();
});
py
::
class_
<
ClassWithSTLVecProperty
>
(
m
,
"ClassWithSTLVecProperty"
)
.
def
(
py
::
init
<>
())
/* Need to cast properties to opaque types to avoid pybind11-internal
STL conversion code from becoming active */
.
def_readwrite
(
"stringList"
,
(
py
::
opaque
<
StringList
>
ClassWithSTLVecProperty
::
*
)
&
ClassWithSTLVecProperty
::
stringList
);
m
.
def
(
"print_opaque_list"
,
[](
py
::
opaque
<
StringList
>
&
_l
)
{
StringList
&
l
=
_l
;
std
::
cout
<<
"Opaque list: "
<<
std
::
endl
;
for
(
auto
entry
:
l
)
std
::
cout
<<
" "
<<
entry
<<
std
::
endl
;
std
::
cout
<<
"Opaque list: ["
;
bool
first
=
true
;
for
(
auto
entry
:
l
)
{
if
(
!
first
)
std
::
cout
<<
", "
;
std
::
cout
<<
entry
;
first
=
false
;
}
std
::
cout
<<
"]"
<<
std
::
endl
;
});
m
.
def
(
"return_void_ptr"
,
[]()
{
return
(
void
*
)
1234
;
});
...
...
example/example14.py
View file @
0871228f
...
...
@@ -4,10 +4,13 @@ import sys
sys
.
path
.
append
(
'.'
)
from
example
import
StringList
,
print_opaque_list
from
example
import
ClassWithSTLVecProperty
from
example
import
return_void_ptr
,
print_void_ptr
from
example
import
return_null_str
,
print_null_str
from
example
import
return_unique_ptr
#####
l
=
StringList
()
l
.
push_back
(
"Element 1"
)
l
.
push_back
(
"Element 2"
)
...
...
@@ -16,9 +19,21 @@ print("Back element is %s" % l.back())
l
.
pop_back
()
print_opaque_list
(
l
)
#####
cvp
=
ClassWithSTLVecProperty
()
print_opaque_list
(
cvp
.
stringList
)
cvp
.
stringList
=
l
cvp
.
stringList
.
push_back
(
"Element 3"
)
print_opaque_list
(
cvp
.
stringList
)
#####
print_void_ptr
(
return_void_ptr
())
print
(
return_null_str
())
print_null_str
(
return_null_str
())
#####
print
(
return_unique_ptr
())
example/example14.ref
View file @
0871228f
Opaque list:
Element 1
Element 2
Opaque list: [Element 1, Element 2]
Back element is Element 2
Opaque list:
Element 1
Opaque list: [Element 1]
Opaque list: []
Opaque list: [Element 1, Element 3]
Got void ptr : 1234
None
Got null str : 0
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment