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
6e213c9c
Commit
6e213c9c
authored
Nov 24, 2015
by
Wenzel Jakob
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
improved shared pointer support (fixes #14)
parent
5e90fa4e
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
89 additions
and
0 deletions
+89
-0
docs/advanced.rst
+8
-0
example/example8.cpp
+36
-0
example/example8.py
+14
-0
example/example8.ref
+0
-0
include/pybind11/cast.h
+13
-0
include/pybind11/pybind11.h
+18
-0
No files found.
docs/advanced.rst
View file @
6e213c9c
...
...
@@ -457,6 +457,14 @@ be declared at the top level before any binding code:
demonstrates how to work with custom reference-counting holder types in
more detail.
.. warning::
To ensure correct reference counting among Python and C++, the use of
``std::shared_ptr<T>`` as a holder type requires that ``T`` inherits from
``std::enable_shared_from_this<T>`` (see cppreference_ for details).
.. _cppreference: http://en.cppreference.com/w/cpp/memory/enable_shared_from_this
.. _custom_constructors:
Custom constructors
...
...
example/example8.cpp
View file @
6e213c9c
...
...
@@ -31,14 +31,36 @@ private:
int
value
;
};
class
MyObject2
:
public
std
::
enable_shared_from_this
<
MyObject2
>
{
public
:
MyObject2
(
int
value
)
:
value
(
value
)
{
std
::
cout
<<
toString
()
<<
" constructor"
<<
std
::
endl
;
}
std
::
string
toString
()
const
{
return
"MyObject2["
+
std
::
to_string
(
value
)
+
"]"
;
}
virtual
~
MyObject2
()
{
std
::
cout
<<
toString
()
<<
" destructor"
<<
std
::
endl
;
}
private
:
int
value
;
};
/// Make pybind aware of the ref-counted wrapper type
PYBIND11_DECLARE_HOLDER_TYPE
(
T
,
ref
<
T
>
);
PYBIND11_DECLARE_HOLDER_TYPE
(
T
,
std
::
shared_ptr
<
T
>
);
Object
*
make_object_1
()
{
return
new
MyObject
(
1
);
}
ref
<
Object
>
make_object_2
()
{
return
new
MyObject
(
2
);
}
MyObject
*
make_myobject_4
()
{
return
new
MyObject
(
4
);
}
ref
<
MyObject
>
make_myobject_5
()
{
return
new
MyObject
(
5
);
}
MyObject2
*
make_myobject2_1
()
{
return
new
MyObject2
(
1
);
}
std
::
shared_ptr
<
MyObject2
>
make_myobject2_2
()
{
return
std
::
make_shared
<
MyObject2
>
(
2
);
}
void
print_object_1
(
const
Object
*
obj
)
{
std
::
cout
<<
obj
->
toString
()
<<
std
::
endl
;
}
void
print_object_2
(
ref
<
Object
>
obj
)
{
std
::
cout
<<
obj
->
toString
()
<<
std
::
endl
;
}
void
print_object_3
(
const
ref
<
Object
>
&
obj
)
{
std
::
cout
<<
obj
->
toString
()
<<
std
::
endl
;
}
...
...
@@ -49,6 +71,11 @@ void print_myobject_2(ref<MyObject> obj) { std::cout << obj->toString() << std::
void
print_myobject_3
(
const
ref
<
MyObject
>
&
obj
)
{
std
::
cout
<<
obj
->
toString
()
<<
std
::
endl
;
}
void
print_myobject_4
(
const
ref
<
MyObject
>
*
obj
)
{
std
::
cout
<<
(
*
obj
)
->
toString
()
<<
std
::
endl
;
}
void
print_myobject2_1
(
const
MyObject2
*
obj
)
{
std
::
cout
<<
obj
->
toString
()
<<
std
::
endl
;
}
void
print_myobject2_2
(
std
::
shared_ptr
<
MyObject2
>
obj
)
{
std
::
cout
<<
obj
->
toString
()
<<
std
::
endl
;
}
void
print_myobject2_3
(
const
std
::
shared_ptr
<
MyObject2
>
&
obj
)
{
std
::
cout
<<
obj
->
toString
()
<<
std
::
endl
;
}
void
print_myobject2_4
(
const
std
::
shared_ptr
<
MyObject2
>
*
obj
)
{
std
::
cout
<<
(
*
obj
)
->
toString
()
<<
std
::
endl
;
}
void
init_ex8
(
py
::
module
&
m
)
{
py
::
class_
<
Object
,
ref
<
Object
>>
obj
(
m
,
"Object"
);
obj
.
def
(
"getRefCount"
,
&
Object
::
getRefCount
);
...
...
@@ -69,5 +96,14 @@ void init_ex8(py::module &m) {
m
.
def
(
"print_myobject_3"
,
&
print_myobject_3
);
m
.
def
(
"print_myobject_4"
,
&
print_myobject_4
);
py
::
class_
<
MyObject2
,
std
::
shared_ptr
<
MyObject2
>>
(
m
,
"MyObject2"
)
.
def
(
py
::
init
<
int
>
());
m
.
def
(
"make_myobject2_1"
,
&
make_myobject2_1
);
m
.
def
(
"make_myobject2_2"
,
&
make_myobject2_2
);
m
.
def
(
"print_myobject2_1"
,
&
print_myobject2_1
);
m
.
def
(
"print_myobject2_2"
,
&
print_myobject2_2
);
m
.
def
(
"print_myobject2_3"
,
&
print_myobject2_3
);
m
.
def
(
"print_myobject2_4"
,
&
print_myobject2_4
);
py
::
implicitly_convertible
<
py
::
int_
,
MyObject
>
();
}
example/example8.py
View file @
6e213c9c
...
...
@@ -8,6 +8,8 @@ from example import make_object_1
from
example
import
make_object_2
from
example
import
make_myobject_4
from
example
import
make_myobject_5
from
example
import
make_myobject2_1
from
example
import
make_myobject2_2
from
example
import
print_object_1
from
example
import
print_object_2
from
example
import
print_object_3
...
...
@@ -16,6 +18,10 @@ from example import print_myobject_1
from
example
import
print_myobject_2
from
example
import
print_myobject_3
from
example
import
print_myobject_4
from
example
import
print_myobject2_1
from
example
import
print_myobject2_2
from
example
import
print_myobject2_3
from
example
import
print_myobject2_4
for
o
in
[
make_object_1
(),
make_object_2
(),
MyObject
(
3
)]:
print
(
"Reference count =
%
i"
%
o
.
getRefCount
())
...
...
@@ -35,3 +41,11 @@ for o in [make_myobject_4(), make_myobject_5(), MyObject(6), 7]:
print_myobject_2
(
o
)
print_myobject_3
(
o
)
print_myobject_4
(
o
)
for
o
in
[
make_myobject2_1
(),
make_myobject2_2
()]:
print
(
o
)
print_myobject2_1
(
o
)
print_myobject2_2
(
o
)
print_myobject2_3
(
o
)
print_myobject2_4
(
o
)
example/example8.ref
View file @
6e213c9c
This diff is collapsed.
Click to expand it.
include/pybind11/cast.h
View file @
6e213c9c
...
...
@@ -517,12 +517,25 @@ protected:
template
<
typename
type
,
typename
holder_type
>
class
type_caster_holder
:
public
type_caster
<
type
>
{
public
:
typedef
type_caster
<
type
>
parent
;
template
<
typename
T
=
holder_type
,
typename
std
::
enable_if
<
std
::
is_same
<
std
::
shared_ptr
<
type
>
,
T
>::
value
,
int
>::
type
=
0
>
bool
load
(
PyObject
*
src
,
bool
convert
)
{
if
(
!
parent
::
load
(
src
,
convert
))
return
false
;
holder
=
holder_type
(((
type
*
)
parent
::
value
)
->
shared_from_this
());
return
true
;
}
template
<
typename
T
=
holder_type
,
typename
std
::
enable_if
<!
std
::
is_same
<
std
::
shared_ptr
<
type
>
,
T
>::
value
,
int
>::
type
=
0
>
bool
load
(
PyObject
*
src
,
bool
convert
)
{
if
(
!
parent
::
load
(
src
,
convert
))
return
false
;
holder
=
holder_type
((
type
*
)
parent
::
value
);
return
true
;
}
explicit
operator
type
*
()
{
return
this
->
value
;
}
explicit
operator
type
&
()
{
return
*
(
this
->
value
);
}
explicit
operator
holder_type
&
()
{
return
holder
;
}
...
...
include/pybind11/pybind11.h
View file @
6e213c9c
...
...
@@ -798,11 +798,29 @@ public:
return
*
this
;
}
private
:
template
<
typename
T
=
holder_type
,
typename
std
::
enable_if
<!
std
::
is_same
<
std
::
shared_ptr
<
type
>
,
T
>::
value
,
int
>::
type
=
0
>
static
void
init_holder
(
PyObject
*
inst_
)
{
instance_type
*
inst
=
(
instance_type
*
)
inst_
;
new
(
&
inst
->
holder
)
holder_type
(
inst
->
value
);
inst
->
constructed
=
true
;
}
template
<
typename
T
=
holder_type
,
typename
std
::
enable_if
<
std
::
is_same
<
std
::
shared_ptr
<
type
>
,
T
>::
value
,
int
>::
type
=
0
>
static
void
init_holder
(
PyObject
*
inst_
)
{
instance_type
*
inst
=
(
instance_type
*
)
inst_
;
try
{
new
(
&
inst
->
holder
)
holder_type
(
inst
->
value
->
shared_from_this
()
);
}
catch
(
const
std
::
bad_weak_ptr
&
)
{
new
(
&
inst
->
holder
)
holder_type
(
inst
->
value
);
}
inst
->
constructed
=
true
;
}
static
void
dealloc
(
PyObject
*
inst_
)
{
instance_type
*
inst
=
(
instance_type
*
)
inst_
;
if
(
inst
->
owned
)
{
...
...
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