Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
f5c154ad
"git@developer.sourcefind.cn:gaoqiong/pybind11.git" did not exist on "f8dafe908e120f8c021fde7739f01eb54a903704"
Commit
f5c154ad
authored
Apr 11, 2016
by
Wenzel Jakob
Browse files
address issue with virtual function dispatch (fixes #159)
parent
50ed3614
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
58 additions
and
5 deletions
+58
-5
example/issues.cpp
example/issues.cpp
+26
-0
example/issues.py
example/issues.py
+19
-0
example/issues.ref
example/issues.ref
+2
-0
include/pybind11/pybind11.h
include/pybind11/pybind11.h
+11
-5
No files found.
example/issues.cpp
View file @
f5c154ad
...
@@ -9,7 +9,25 @@
...
@@ -9,7 +9,25 @@
#include "example.h"
#include "example.h"
struct
Base
{
virtual
void
dispatch
(
void
)
const
=
0
;
};
struct
DispatchIssue
:
Base
{
virtual
void
dispatch
(
void
)
const
{
PYBIND11_OVERLOAD_PURE
(
void
,
Base
,
dispatch
);
}
};
void
dispatch_issue_go
(
const
Base
*
b
)
{
b
->
dispatch
();
}
PYBIND11_PLUGIN
(
mytest
)
{
pybind11
::
module
m
(
"mytest"
,
"A test"
);
return
m
.
ptr
();
}
void
init_issues
(
py
::
module
&
m
)
{
void
init_issues
(
py
::
module
&
m
)
{
py
::
module
m2
=
m
.
def_submodule
(
"issues"
);
py
::
module
m2
=
m
.
def_submodule
(
"issues"
);
...
@@ -18,4 +36,12 @@ void init_issues(py::module &m) {
...
@@ -18,4 +36,12 @@ void init_issues(py::module &m) {
// #150: char bindings broken
// #150: char bindings broken
m2
.
def
(
"print_char"
,
[](
char
c
)
{
std
::
cout
<<
c
<<
std
::
endl
;
});
m2
.
def
(
"print_char"
,
[](
char
c
)
{
std
::
cout
<<
c
<<
std
::
endl
;
});
// #159: virtual function dispatch has problems with similar-named functions
pybind11
::
class_
<
DispatchIssue
>
base
(
m2
,
"DispatchIssue"
);
base
.
alias
<
Base
>
()
.
def
(
pybind11
::
init
<>
())
.
def
(
"dispatch"
,
&
Base
::
dispatch
);
m2
.
def
(
"dispatch_issue_go"
,
&
dispatch_issue_go
);
}
}
example/issues.py
View file @
f5c154ad
...
@@ -4,6 +4,25 @@ import sys
...
@@ -4,6 +4,25 @@ import sys
sys
.
path
.
append
(
'.'
)
sys
.
path
.
append
(
'.'
)
from
example.issues
import
print_cchar
,
print_char
from
example.issues
import
print_cchar
,
print_char
from
example.issues
import
DispatchIssue
,
dispatch_issue_go
print_cchar
(
"const char *"
)
print_cchar
(
"const char *"
)
print_char
(
'c'
)
print_char
(
'c'
)
class
PyClass1
(
DispatchIssue
):
def
dispatch
(
self
):
print
(
"Yay.."
)
class
PyClass2
(
DispatchIssue
):
def
dispatch
(
self
):
try
:
super
(
PyClass2
,
self
).
dispatch
()
except
Exception
as
e
:
print
(
"Failed as expected: "
+
str
(
e
))
p
=
PyClass1
()
dispatch_issue_go
(
p
)
b
=
PyClass2
()
dispatch_issue_go
(
b
)
example/issues.ref
View file @
f5c154ad
const char *
const char *
c
c
Failed as expected: Tried to call pure virtual function "dispatch"
Yay..
include/pybind11/pybind11.h
View file @
f5c154ad
...
@@ -1032,8 +1032,8 @@ inline function get_overload(const void *this_ptr, const char *name) {
...
@@ -1032,8 +1032,8 @@ inline function get_overload(const void *this_ptr, const char *name) {
handle
type
=
py_object
.
get_type
();
handle
type
=
py_object
.
get_type
();
auto
key
=
std
::
make_pair
(
type
.
ptr
(),
name
);
auto
key
=
std
::
make_pair
(
type
.
ptr
(),
name
);
/* Cache functions that aren't overloaded in
p
ython to avoid
/* Cache functions that aren't overloaded in
P
ython to avoid
many costly dictionary lookups
in Python
*/
many costly
Python
dictionary lookups
below
*/
auto
&
cache
=
detail
::
get_internals
().
inactive_overload_cache
;
auto
&
cache
=
detail
::
get_internals
().
inactive_overload_cache
;
if
(
cache
.
find
(
key
)
!=
cache
.
end
())
if
(
cache
.
find
(
key
)
!=
cache
.
end
())
return
function
();
return
function
();
...
@@ -1044,10 +1044,16 @@ inline function get_overload(const void *this_ptr, const char *name) {
...
@@ -1044,10 +1044,16 @@ inline function get_overload(const void *this_ptr, const char *name) {
return
function
();
return
function
();
}
}
/* Don't call dispatch code if invoked from overridden function */
PyFrameObject
*
frame
=
PyThreadState_Get
()
->
frame
;
PyFrameObject
*
frame
=
PyThreadState_Get
()
->
frame
;
pybind11
::
str
caller
=
pybind11
::
handle
(
frame
->
f_code
->
co_name
).
str
();
if
((
std
::
string
)
pybind11
::
handle
(
frame
->
f_code
->
co_name
).
str
()
==
name
&&
if
((
std
::
string
)
caller
==
name
)
frame
->
f_code
->
co_argcount
>
0
)
{
return
function
();
PyFrame_FastToLocals
(
frame
);
PyObject
*
self_caller
=
PyDict_GetItem
(
frame
->
f_locals
,
PyTuple_GET_ITEM
(
frame
->
f_code
->
co_varnames
,
0
));
if
(
self_caller
==
py_object
.
ptr
())
return
function
();
}
return
overload
;
return
overload
;
}
}
...
...
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