mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 21:25:13 +00:00
enable passing C++ instances to void*-valued arguments
This commit is contained in:
parent
e8b9dd263c
commit
772c6d54d6
@ -49,10 +49,10 @@ void init_ex14(py::module &m) {
|
|||||||
std::cout << "]" << std::endl;
|
std::cout << "]" << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
m.def("return_void_ptr", []() { return (void *) 1234; });
|
m.def("return_void_ptr", []() { return (void *) 0x1234; });
|
||||||
m.def("print_void_ptr", [](void *ptr) { std::cout << "Got void ptr : " << (uint64_t) ptr << std::endl; });
|
m.def("print_void_ptr", [](void *ptr) { std::cout << "Got void ptr : 0x" << std::hex << (uint64_t) ptr << std::endl; });
|
||||||
m.def("return_null_str", []() { return (char *) nullptr; });
|
m.def("return_null_str", []() { return (char *) nullptr; });
|
||||||
m.def("print_null_str", [](char *ptr) { std::cout << "Got null str : " << (uint64_t) ptr << std::endl; });
|
m.def("print_null_str", [](char *ptr) { std::cout << "Got null str : 0x" << std::hex << (uint64_t) ptr << std::endl; });
|
||||||
|
|
||||||
m.def("return_unique_ptr", []() -> std::unique_ptr<StringList> {
|
m.def("return_unique_ptr", []() -> std::unique_ptr<StringList> {
|
||||||
StringList *result = new StringList();
|
StringList *result = new StringList();
|
||||||
|
@ -35,6 +35,11 @@ print_opaque_list(cvp.stringList)
|
|||||||
print_void_ptr(return_void_ptr())
|
print_void_ptr(return_void_ptr())
|
||||||
print_void_ptr(Example1()) # Should also work for other C++ types
|
print_void_ptr(Example1()) # Should also work for other C++ types
|
||||||
|
|
||||||
|
try:
|
||||||
|
print_void_ptr([1, 2, 3]) # This should not work
|
||||||
|
except Exception as e:
|
||||||
|
print("Caught expected exception: " + str(e))
|
||||||
|
|
||||||
print(return_null_str())
|
print(return_null_str())
|
||||||
print_null_str(return_null_str())
|
print_null_str(return_null_str())
|
||||||
|
|
||||||
|
@ -5,8 +5,14 @@ Back element is Element 2
|
|||||||
Opaque list: [Element 1]
|
Opaque list: [Element 1]
|
||||||
Opaque list: []
|
Opaque list: []
|
||||||
Opaque list: [Element 1, Element 3]
|
Opaque list: [Element 1, Element 3]
|
||||||
Got void ptr : 1234
|
Got void ptr : 0x1234
|
||||||
|
Called Example1 default constructor..
|
||||||
|
Got void ptr : 0x7f9ba0f3c430
|
||||||
|
Called Example1 destructor (0)
|
||||||
|
Caught expected exception: Incompatible function arguments. The following argument types are supported:
|
||||||
|
1. (capsule) -> NoneType
|
||||||
|
|
||||||
None
|
None
|
||||||
Got null str : 0
|
Got null str : 0x0
|
||||||
<example.StringList object at 0x104a47500>
|
<example.StringList object at 0x10d3277a0>
|
||||||
Opaque list: [some value]
|
Opaque list: [some value]
|
||||||
|
@ -52,15 +52,18 @@ PYBIND11_NOINLINE inline internals &get_internals() {
|
|||||||
return *internals_ptr;
|
return *internals_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
PYBIND11_NOINLINE inline detail::type_info* get_type_info(PyTypeObject *type) {
|
PYBIND11_NOINLINE inline detail::type_info* get_type_info(PyTypeObject *type, bool throw_if_missing = true) {
|
||||||
auto const &type_dict = get_internals().registered_types_py;
|
auto const &type_dict = get_internals().registered_types_py;
|
||||||
do {
|
do {
|
||||||
auto it = type_dict.find(type);
|
auto it = type_dict.find(type);
|
||||||
if (it != type_dict.end())
|
if (it != type_dict.end())
|
||||||
return (detail::type_info *) it->second;
|
return (detail::type_info *) it->second;
|
||||||
type = type->tp_base;
|
type = type->tp_base;
|
||||||
if (!type)
|
if (!type) {
|
||||||
|
if (throw_if_missing)
|
||||||
pybind11_fail("pybind11::detail::get_type_info: unable to find type object!");
|
pybind11_fail("pybind11::detail::get_type_info: unable to find type object!");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,13 +385,24 @@ public:
|
|||||||
value = nullptr;
|
value = nullptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if this is a capsule */
|
||||||
capsule c(h, true);
|
capsule c(h, true);
|
||||||
if (!c.check())
|
if (c.check()) {
|
||||||
return false;
|
|
||||||
value = (void *) c;
|
value = (void *) c;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if this is a C++ type */
|
||||||
|
if (get_type_info((PyTypeObject *) h.get_type().ptr(), false)) {
|
||||||
|
value = ((instance<void> *) h.ptr())->value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fail */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static handle cast(const void *ptr, return_value_policy /* policy */, handle /* parent */) {
|
static handle cast(const void *ptr, return_value_policy /* policy */, handle /* parent */) {
|
||||||
if (ptr)
|
if (ptr)
|
||||||
return capsule(ptr).release();
|
return capsule(ptr).release();
|
||||||
|
@ -450,7 +450,7 @@ protected:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
} else {
|
} else {
|
||||||
if (overloads->is_constructor) {
|
if (overloads->is_constructor) {
|
||||||
/* When a construtor ran successfully, the corresponding
|
/* When a constructor ran successfully, the corresponding
|
||||||
holder type (e.g. std::unique_ptr) must still be initialized. */
|
holder type (e.g. std::unique_ptr) must still be initialized. */
|
||||||
PyObject *inst = PyTuple_GetItem(args, 0);
|
PyObject *inst = PyTuple_GetItem(args, 0);
|
||||||
auto tinfo = detail::get_type_info(Py_TYPE(inst));
|
auto tinfo = detail::get_type_info(Py_TYPE(inst));
|
||||||
|
Loading…
Reference in New Issue
Block a user