首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不透明向量的Pybind11访问

不透明向量的Pybind11访问
EN

Stack Overflow用户
提问于 2019-06-28 18:42:17
回答 2查看 2.4K关注 0票数 3

为了能够在PythonandC++之间引用传递自定义类型的向量,我的项目对我的类型的向量使用了PYBIND11_MAKE_OPAQUEpybind11::bind_vector<>--但是--我也需要使用自定义类型的向量。下面是一个例子。

代码语言:javascript
复制
#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代码示例。

代码语言:javascript
复制
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]

错误消息:

代码语言:javascript
复制
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类上重载索引运算符?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-28 19:13:03

该示例有效,但我的代码没有工作。这是因为在我的代码中,1D向量类绑定到不同pybind11模块中的Python。因此,当一维向量C++类型为2D向量类定义__getitem__时,它没有映射的Python类型。但是,我认为,如果稍后导入包含1D向量Python类型bind的模块,它应该可以工作,但它不工作。那可能是个窃听器。

编辑:

这种行为不是一个bug (我想,Jakob似乎是个相当聪明的家伙)。正如在绑定STL容器的手册中所讨论的,有一个关于“模块本地”绑定的部分。默认情况下,类型绑定是定义在其中的模块的本地绑定,以避免同一类型的多个不同绑定。

然而,我们的项目包含一个“数据类型”模块,以及许多使用这些类型的模块。在这种情况下,我们不希望在" datatypes“模块中定义的数据类型是本地模块。否则,我们最终会遇到返回值没有转换为正确的Python类型的问题。

我们可以关闭绑定定义中的默认模块本地绑定。使用问题的示例,我们可以关闭ExampleVector的模块本地绑定,访问Example2DVector (在另一个模块中定义)将不再失败。

代码语言:javascript
复制
pybind11::bind_vector<std::vector<Example>>(m, "ExampleVector", pybind11::module_local(false));
票数 2
EN

Stack Overflow用户

发布于 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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56811833

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档