Работа с VS 2019, Python 3.7 64bit на Windows 10 и pybind11 2.4.3 Я столкнулся со следующей проблемой:
Когда я создаю объект с pybind11 py::class_
на Python и передают его непосредственно методу на стороне C ++, хранящем его в std :: vector, попытка прочитать объект позже из Python приводит к Access violation - no RTTI data
. Если код Python сначала сохраняет созданный объект в переменной Python, а затем передает его в C ++, то последующий доступ из Python работает как задумано.
У меня нет большого опыта использования pybind11 и C ++, так что я, вероятно, делаю простую ошибку, был бы признателен за любую помощь в том, как настроить использование C ++ и pybind11 так, чтобы обходной путь Python для использования переменной не требовался, и я не получил никакого нарушения доступа.
Вот некоторые детали кода, код C ++ -
#include <iostream>
#include <vector>
#include <pybind11/pybind11.h>
using namespace std;
class XdmItem;
class XdmValue {
public:
virtual XdmItem* itemAt(int n);
virtual int size();
void addXdmItem(XdmItem* val);
protected:
std::vector<XdmItem*> values;
};
void XdmValue::addXdmItem(XdmItem* val) {
values.push_back(val);
}
XdmItem* XdmValue::itemAt(int n) {
if (n >= 0 && (unsigned int)n < values.size()) {
return values[n];
}
return NULL;
}
int XdmValue::size() {
return values.size();
}
class XdmItem : public XdmValue {
public:
int size();
};
int XdmItem::size() {
return 1;
}
namespace py = pybind11;
PYBIND11_MODULE(UseClassHierarchyAsPythonModule, m) {
py::class_<XdmValue>(m, "PyXdmValue")
.def(py::init<>())
.def("size", &XdmValue::size)
.def("item_at", &XdmValue::itemAt)
.def("add_item", &XdmValue::addXdmItem);
py::class_<XdmItem, XdmValue>(m, "PyXdmItem")
.def(py::init<>())
.def("size", &XdmItem::size);
#ifdef VERSION_INFO
m.attr("__version__") = VERSION_INFO;
#else
m.attr("__version__") = "dev";
#endif
}
, код Python, который работает безупречно, -
import UseClassHierarchyAsPythonModule
value = UseClassHierarchyAsPythonModule.PyXdmValue()
print(value, type(value))
print(value.size())
item = UseClassHierarchyAsPythonModule.PyXdmItem()
value.add_item(item)
print(value.size())
item0 = value.item_at(0)
print(item, type(item))
, тогда как следующий код вызывает Access violation - no RTTI data!
:
import UseClassHierarchyAsPythonModule
value = UseClassHierarchyAsPythonModule.PyXdmValue()
print(value, type(value))
print(value.size())
value.add_item(UseClassHierarchyAsPythonModule.PyXdmItem())
print(value.size())
item0 = value.item_at(0)
print(item, type(item))
Это дает
Message=Access violation - no RTTI data!
Source=C:\SomePath\AccessViolation.py
StackTrace:
File "C:\SomePath\AccessViolation.py", line 13, in <module>
item0 = value.item_at(0)
Если я включаю отладку собственного кода, трассировка стека включает код Pybind C ++ и имеет значение
> UseClassHierarchyAsPythonModule.pyd!pybind11::polymorphic_type_hook<XdmItem,void>::get(const XdmItem * src, const type_info * & type) Line 818 C++
UseClassHierarchyAsPythonModule.pyd!pybind11::detail::type_caster_base<XdmItem>::src_and_type(const XdmItem * src) Line 851 C++
UseClassHierarchyAsPythonModule.pyd!pybind11::detail::type_caster_base<XdmItem>::cast(const XdmItem * src, pybind11::return_value_policy policy, pybind11::handle parent) Line 871 C++
UseClassHierarchyAsPythonModule.pyd!pybind11::cpp_function::initialize::__l2::<lambda>(pybind11::detail::function_call & call) Line 163 C++
UseClassHierarchyAsPythonModule.pyd!pybind11::handle <lambda>(pybind11::detail::function_call &)::<lambda_invoker_cdecl>(pybind11::detail::function_call & call) Line 100 C++
UseClassHierarchyAsPythonModule.pyd!pybind11::cpp_function::dispatcher(_object * self, _object * args_in, _object * kwargs_in) Line 624 C++
[External Code]
AccessViolation.py!<module> Line 13 Python
Любая идея, что неправильно в моем C ++ / pybind11?