【发布时间】:2017-06-30 10:20:36
【问题描述】:
我使用 Boost::Python 已经有一段时间了,结果一切正常。但是昨天我试图找出为什么我认为我已经注册的特定类型(元组)在我尝试从 Python 访问它时给了我错误。
事实证明,虽然元组实际已注册,但当尝试通过 std::vector 包装的 vector_indexing_suite 访问它时,这已经不够了。
我想知道,为什么它不起作用?有什么办法可以使这项工作?我应该尝试手动包装矢量吗?
下面是我的 MVE:
#include <tuple>
#include <vector>
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
template <typename T>
struct TupleToPython {
TupleToPython() {
boost::python::to_python_converter<T, TupleToPython<T>>();
}
template<int...>
struct sequence {};
template<int N, int... S>
struct generator : generator<N-1, N-1, S...> { };
template<int... S>
struct generator<0, S...> {
using type = sequence<S...>;
};
template <int... I>
static boost::python::tuple boostConvertImpl(const T& t, sequence<I...>) {
return boost::python::make_tuple(std::get<I>(t)...);
}
template <typename... Args>
static boost::python::tuple boostConvert(const std::tuple<Args...> & t) {
return boostConvertImpl(t, typename generator<sizeof...(Args)>::type());
}
static PyObject* convert(const T& t) {
return boost::python::incref(boostConvert(t).ptr());
}
};
using MyTuple = std::tuple<int>;
using Tuples = std::vector<MyTuple>;
MyTuple makeMyTuple() {
return MyTuple();
}
Tuples makeTuples() {
return Tuples{MyTuple()};
}
BOOST_PYTHON_MODULE(h)
{
using namespace boost::python;
TupleToPython<MyTuple>();
def("makeMyTuple", makeMyTuple);
class_<std::vector<MyTuple>>{"Tuples"}
.def(vector_indexing_suite<std::vector<MyTuple>>());
def("makeTuples", makeTuples);
}
通过 Python 访问生成的 .so 会导致:
>>> print makeMyTuple()
(0,)
>>> print makeTuples()[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: No Python class registered for C++ class std::tuple<int>
>>>
编辑:
我已经意识到如果 vector_indexing_suite 与 NoProxy 参数设置为 true 一起使用,则不会发生错误。但是,如果这不是必需的,我更愿意这样做,因为这会使导出的类在 Python 中不直观。
【问题讨论】:
-
不应该
Tuples makeTuples() { return Tuples{MyTuple()}; }改为Tuples makeTuples() { return Tuples(); }吗? -
@fedepad 我这样做是为了让您可以在不触发
out_of_bounds错误的情况下调用makeTuples()[0],因为那时向量将为空并且您不会看到元组错误。
标签: python c++ boost tuples boost-python