为了能够在PythonandC++之间引用传递自定义类型的向量,我的项目对我的类型的向量使用了PYBIND11_MAKE_OPAQUE和pybind11::bind_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类上重载索引运算符?
发布于 2019-06-28 19:13:03
该示例有效,但我的代码没有工作。这是因为在我的代码中,1D向量类绑定到不同pybind11模块中的Python。因此,当一维向量C++类型为2D向量类定义__getitem__时,它没有映射的Python类型。但是,我认为,如果稍后导入包含1D向量Python类型bind的模块,它应该可以工作,但它不工作。那可能是个窃听器。
编辑:
这种行为不是一个bug (我想,Jakob似乎是个相当聪明的家伙)。正如在绑定STL容器的手册中所讨论的,有一个关于“模块本地”绑定的部分。默认情况下,类型绑定是定义在其中的模块的本地绑定,以避免同一类型的多个不同绑定。
然而,我们的项目包含一个“数据类型”模块,以及许多使用这些类型的模块。在这种情况下,我们不希望在" datatypes“模块中定义的数据类型是本地模块。否则,我们最终会遇到返回值没有转换为正确的Python类型的问题。
我们可以关闭绑定定义中的默认模块本地绑定。使用问题的示例,我们可以关闭ExampleVector的模块本地绑定,访问Example2DVector (在另一个模块中定义)将不再失败。
pybind11::bind_vector<std::vector<Example>>(m, "ExampleVector", pybind11::module_local(false));发布于 2019-06-30 14:05:46
引用表格文档:
此宏必须在顶级(以及任何命名空间之外)指定,因为它实例化了部分模板重载。如果您的绑定代码由多个编译单元组成,那么它必须出现在每个文件中(通常是通过公共头),而不是在使用std::vector之前。不透明类型还必须有相应的class_声明,才能将它们与Python中的名称关联起来,并定义一组可用的操作。
@ktb,这不是一个bug,请看https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html?highlight=compilation%20unit#making-opaque-types
https://stackoverflow.com/questions/56811833
复制相似问题