问题标签 [pybind11]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - Pybind - 奇怪地重复出现的模板
我有以下类结构(我的实际实现的简化示例):
接着
我松散地基于这个问题PyBind11 Template Class of Many Types的答案。但是我得到的错误是:
C2783 'pybind11::class_> &pybind11::class_>::def(const char *,Func &&,const Extra &...)': 无法推断 'Func' 的模板参数 ...\source.cpp 10
C2672 'pybind11::class_>::def': 找不到匹配的重载函数 ...\source.cpp 12
它似乎与template <class FuncType>
我无法在任何地方定义的第二个有关,因为func
稍后将传入通用函数。有什么办法可以规避这个问题吗?
c++ - 基于节点的树结构的 Python 绑定
语境
我正在开发一个2D 动画系统,其中数据组织为基于节点的树结构,其语义和功能与XML DOM非常相似——但不太相似,无法仅使用现有的 XML 实现。为了清楚起见,让我们简化并假设数据结构是通过以下伪代码在概念上定义的:
遵循现代 C++ 的最新指南(Core Guidelines、Herb Sutter talk等),一个合适的选择是使用智能指针来拥有句柄,而原始指针用于非拥有句柄。由于所有权是唯一的,因此std::unique_ptr
是有道理的:
此 API 假定客户端代码知道它在做什么。就像使用 a 时一样list::iterator
,客户端需要阅读文档以了解哪些操作可能会使节点无效,并注意不要盲目地将 aNode*
作为数据成员并在以后取消引用它,因为它可能是悬空的。对于 C++ 客户,我支持这种方法:我相信这是惯用的 C++,并且是您为性能付出的代价。
但是,我绝对需要为 Python 客户端提供更多安全性。动画软件是一个带有嵌入式 Python 控制台的 C++ GUI 程序,这意味着许多 Python 客户预计将是几乎没有编程经验的艺术家,主要是从教程中复制粘贴代码并对其进行调整以适应他们的需求。更糟糕的是,这种不可靠的未经测试的 Python 代码可能会在用户处于具有潜在价值的未保存数据的长期交互会话中时执行。当 Python 客户端尝试使用过期节点时,软件绝对不会崩溃。预期的行为类似于:
问题
您将如何使用 pybind11 包装此 C++ API 以获得预期的行为?
如有必要,您将如何更改 C++ API 以允许此类行为,和/或使包装器代码更具可读性、惯用性等?
我已经尝试或考虑过的
天真的包装 asclass_<Node>(m, "Node")
不起作用:Python 实例无法知道节点是否仍然有效。基本上,返回Node*
viatake_ownership
会导致双重删除,返回它们 viareference
或reference_internal
会导致未定义的行为(读取、分段错误)。
所以我们要么需要一些PyNode
蹦床类通过其他方式跟踪节点的有效性(例如,注册回调,如Node::onAboutToDie()
),要么更改 C++ 所有权模型以使用引用计数的智能指针。
我认为一个不错的选择是将 C++ 代码更改为使用shared_ptr
而不是unique_ptr
. 我会Node
派生自enable_shared_from_this
,并将其包装为class_<Node, PyWeakPtr<Node>>(m, "Node")
在引擎盖下PyWeakPtr
存储 a 的自定义持有人的位置。weak_ptr
由于节点派生自enable_shared_from_this
,因此持有者可以有一个PyWeakPtr(T*)
构造函数将原始指针转换为weak_ptr
. 简而言之,这将利用共享指针的引用计数能力不具有共享所有权(所有权仍然是唯一的),而只是为了能够在 Python 端使用弱引用,这将检查expired()
在每次访问之前,如果过期则抛出一个可捕获的异常。然而,到目前为止,我的各种尝试都失败了:要么我无法获得预期的行为,要么我什至无法让它们编译,等等。
一个更明显的解决方案也是shared_ptr
使用class_<Node, std::shared_ptr<Node>>(m, "Node")
而不是我们的自定义 holder PyWeakPtr
,但它也不起作用,因为只要一些 python 变量指向节点,它就会人为地延长节点的生命周期。我认为这是一个泄漏:节点不应该被共享,如果用户在 UI 中删除一个节点,它应该消失并且立即调用析构函数。语义确实应该是在 Python 中访问“语义删除”节点会引发 Python 错误(不会使 C++ 程序崩溃),而不是默默地伪装成有效节点。
如果有用,我可能会花时间清理/make_minimal/etc 中的一些尝试,但是为了简洁起见,现在我将保留问题,也许这里的一些专家已经有了一些有用的见解,例如整个方法是否甚至是有道理的,等等 :)
请注意,许多解决类似问题的现有软件(例如 QtQDomDocument
或 Pixar 的通用场景描述)即使在 C++ API 中也倾向于使用引用计数的弱引用(或多或少在内部隐藏),从而完全屏蔽了 C++ 和 Python 客户端等错误。我也对这种方法持开放态度,尽管理想情况下,我认为我更愿意坚持在 C++ 中简单地使用非拥有原始指针的一般准则。
python - Pybind:是否可以告知 Python 构造函数的参数名称?
在 Pybind 中,可以告知 Python函数参数的名称:
(http://pybind11.readthedocs.io/en/stable/basics.html#keyword-arguments)
构造函数有类似的东西吗?Spyder (Anaconda) 默认已经显示函数的输入参数,但是对于构造函数,“帮助”只显示:(*args, **kwargs)。
python - setup.py:添加安装所需的依赖项
为了在 PyPi 上分发 Python 库,我通常在setup.py
à la中指定包的依赖项
然而,在某些情况下,我已经需要在 中导入一些东西setup.py
,例如在使用 pybind11 时。查找 pybind11 包含目录的推荐方法是通过
因此,用户需要在pip 尝试安装库本身pybind11
之前安装。不幸的是,简单地添加模块install_requires
并不能减少它:一个得到
尝试安装时。有没有办法在评估之前强制安装需求setup.py
?
python - 从 python 传递到 C++ 的数组中未映射的内存访问
我正在使用pybind11
.
它numpy.array
在其构造函数中接受 a,并获取指向其内部数据的指针。(它不复制数据)。
我有另一个接受 a 的类const Data&
,从而可以访问数组数据。
这里这两个类使用 pybind11 暴露给 python:
这运作良好。我可以导入我的模块,Data
从 a 创建一个实例numpy.array
,然后将其传递给Manager
:
我的脚本运行良好,您可以看到我的 C++ 代码访问numpy.array
数据并将其地址和第一个元素打印到标准输出:
我创建以上所有内容都是为了创建一个MCVE来说明我在下面遇到的问题。
但是,现在我加载了我拥有的 pandas DataFrame pickle 文件(这里是有问题的 pickle 文件的下载链接):
我的 C++ 代码在尝试访问数组数据时崩溃。
这是标准输出:
所以指向数组的指针在 中是相同的Manager
,但是尝试取消引用指针会导致 SEGV。
通过 valgrind 运行它,valgrind 报告Access not within mapped region at address 0x7f8864241010
(即: 的地址numpy.array
)。
Python 对我的 pickle 文件非常满意:
我一生都无法弄清楚我的泡菜文件出了什么问题。
- 我试过创建一个
numpy.array
酸洗,效果很好 - 我试过创建一个
pandas.DataFrame
酸洗,效果很好 - 我已经分割了我的“无效”数据框,我可以得到一个工作正常的子集
我的数据中有一些东西让 python 很高兴,但会导致 C++ 中的 SEGV。
我该如何诊断?
pybind11 - 用于 STL-vector-like 类的健壮类型脚轮
我有一个与 STL-vector 非常相似的类(差异对于 pybind11 类型的 caster 并不重要,因此我将在这里忽略它们)。我为这个类写了一个类型转换。下面给出了我的代码的最小工作示例。显示问题的示例包含在代码下方。
问题是我的脚轮很有限(因为我用过py::array_t
)。原则上,该接口确实接受元组、列表和 numpy 数组。但是,当我基于 typename 重载时,输入的元组和列表的接口失败(即使它是不正确的类型,也只是选择了第一个重载)。
我的问题是:如何使类型脚轮更健壮?是否有一种有效的方法可以将尽可能多的现有类型转换器重用于类似 STL 向量的类?
C++代码(包括pybind11接口)
例子
输出:
python - sphinx 删除自动模块中 args 的模块前缀
我知道如何通过设置“add_module_names = False”来删除自动模块指令中函数的模块前缀。 从 sphinx 函数中删除包和模块名称
但是它不能删除 automodule 指令中 args 的模块前缀。下面是automodule生成的文档。
您可以看到 self arg 的数据类型有一个长前缀,例如“PyPhysLeo.data_core”。
data_core 子模块
class BufferDataD 同时管理CPU缓冲区和GPU缓冲区的类,数据类型为double
CPU2GPU(self: PyPhysLeo.data_core.BufferDataD) → 无
GPU2CPU(self: PyPhysLeo.data_core.BufferDataD) → 无
分配CPU(自我:PyPhysLeo.data_core.BufferDataD)→无
allocateGPU(self: PyPhysLeo.data_core.BufferDataD) → 无
setZeroCPU(self: PyPhysLeo.data_core.BufferDataD) → 无
setZeroGPU(self: PyPhysLeo.data_core.BufferDataD) → 无
大小(自我:PyPhysLeo.data_core.BufferDataD)→ int
python - setup.py下如何设置多个包目录
有谁知道如何在 setup.py 中设置多个包目录
包=['package_1', 'package_2'], package_dir={??,??}
考虑到两个包都在不同的文件夹下。
谢谢
c++ - 通过 pybind11 从 C++ 使用 scipy
我希望有可能使用C++ 中的numpy、scipy等 python 模块。以下代码尝试调用scipy.optimize.curve_fit来拟合抛物线函数。调用curve_fit时出现问题。在这里,抛出异常。
异常提供以下信息:
ValueError: no signature found for builtin < 0x00000204FFE9C630 处 PyCapsule 对象的内置方法>
在:
D:\Programs\python36_6_x64\Lib\inspect.py(2090):_signature_from_builtin D:\Programs\python36_6_x64\Lib\inspect.py(2266):_signature_from_callable D:\Programs\python36_6_x64\Lib\inspect.py(2802 ): from_callable D:\Programs\python36_6_x64\Lib\inspect.py(3052): 签名 D:\Programs\python36_6_x64\lib\site-packages\scipy_lib_util.py(290): getargspec_no_self
D:\Programs\python36_6_x64\lib\站点包\scipy\optimize\minpack.py(685):curve_fit
如何正确地从 C++ 调用 curve_fit?
python - 拆分 pybind11 模块和自动类型转换的问题
我有一组用 C++ 编写并使用 pybind11 导出到 Python 的模块。所有这些模块都应该能够独立使用,但它们使用一组在实用程序库中定义的通用自定义类型。
在每个模块中都有类似于下面的代码。标Color.hpp
头定义了实用程序库中使用的类型。
当然,这是行不通的。Pybind 不知道如何对Color
对象进行类型转换。答案(或希望不是)是将Color
类定义为模块的一部分。之后,pybind 能够进行自动类型转换。
理想情况下,我想将所有这些自定义实用程序类型和相关函数保存在一个单独的模块中,与所有使用它们的模块分开。但是我需要在使用它的每个模块中定义类型转换,或者以其他方式引用它。我该怎么做?我不想要pb11_example_module.Color
等等utils.Color
。我不知道它们的兼容性,这似乎是错误的方式。