为了能够在Python和C ++之间通过引用传递自定义类型的向量,我的项目对我类型的向量使用了PYBIND11_MAKE_OPAQUE
和pybind11::bind_vector<>
。 但是 ,我还需要使用自定义类型的vector向量。下面是一个示例。
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <vector>
class Example {};
PYBIND11_MAKE_OPAQUE(std::vector<Example>);
PYBIND11_MAKE_OPAQUE(std::vector<std::vector<Example>>);
PYBIND11_MODULE(ExModule, m)
{
pybind11::class_<Example>(m, "Example")
.def(pybind11::init<>());
pybind11::bind_vector<std::vector<Example>>(m, "ExampleVector");
pybind11::bind_vector<std::vector<std::vector<Example>>>(m, "Example2DVector");
}
如果我在Python中创建自己类型的2D向量,然后尝试访问它,则会收到错误消息。下面是示例Python代码。
from ExModule import Example, ExampleVector, Example2DVector
# a is a 10x10 vector of Examples
a = Example2DVector([ExampleVector([Example() for i in range(10)]) for i in range(10)])
b = a[4]
错误消息:
TypeError: Unable to convert function return value to a Python type! The signature was
(self: ExModule.Example2DVector, arg0: int) -> std::vector<Example, std::allocator<Example> >
这似乎是因为2D向量类型上的索引操作的返回类型是不透明类型。我认为应该发生的是,应将收益构建为ExampleVector
。我无法从Python做到这一点,它必须在模块包装器中完成。这是错误还是功能缺失?如果没有,如何在Example2DVector
类上重载索引运算符?
答案 0 :(得分:0)
该示例有效,但我的代码无效。这是由于以下事实:在我的代码中,一维向量类在另一个pybind11模块中绑定到Python类型。因此,当它为2D向量类定义__getitem__
时,没有1D向量C ++类型的映射Python类型。但是,我认为,如果稍后导入包含一维矢量Python类型绑定的模块,它应该可以工作,但不能。那可能是一个错误。
编辑:
这种行为不是错误(我认为,雅各布似乎是一个非常聪明的人)。如cvxpy中有关绑定STL容器的讨论,其中有一节涉及“模块本地”绑定。默认情况下,类型绑定在定义它们的模块中是本地的,以避免相同类型的多个不同绑定。
但是,我们的项目包含一个“数据类型”模块,以及许多使用这些类型的模块。在这种情况下,我们不希望在“数据类型”模块中定义的数据类型是模块本地的。否则,我们将面临给定的问题,即返回值未转换为正确的Python类型。
我们可以在绑定定义中关闭默认的模块本地绑定。使用问题的示例,我们可以为ExampleVector
关闭模块本地绑定,并且对Example2DVector
(在另一个模块中定义)的访问将不再失败。
pybind11::bind_vector<std::vector<Example>>(m, "ExampleVector", pybind11::module_local(false));
答案 1 :(得分:0)
引用表单文档:
此宏必须在顶层(并且在任何名称空间之外)指定,因为它实例化了部分模板重载。如果绑定代码由多个编译单元组成,则在使用std :: vector之前,它必须存在于每个文件中(通常通过公共标头)。不透明类型还必须具有相应的class_声明,才能将它们与Python中的名称相关联,并定义一组可用的操作
@ktb,这不是错误,请参阅https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html?highlight=compilation%20unit#making-opaque-types