标签: pybind11

如何使用 pybind11 包装单例类?

我有一个 C++ 中的单例类(没有公共构造函数,C++ 程序员调用 class.instance() 来创建单例或返回现有的单例)。

我更愿意在 Python 级别隐藏它。如果我正在编写一个 Python 单例,我会在__new__. 如果一个类没有公共构造函数,我认为我无法创建__init__包装器(我的尝试失败了)。我在 pybind11 文档中没有看到提及__new__(尽管可能错过了它,并且 Google 似乎很乐意省略下划线包含“new”的返回页面,但没有提及__new__)。

pybind11(甚至Boost.Python)有单例配方吗?

pybind11

7
推荐指数
1
解决办法
3064
查看次数

PyBind11 全局级枚举

PyBind11 文档讨论了使用enum here

显示的示例假定枚举嵌入在一个类中,如下所示:

struct Pet {
    enum Kind {
        Dog = 0,
        Cat
    };

    Pet(const std::string &name, Kind type) : name(name), type(type) { }

    std::string name;
    Kind type;
};

py::class_<Pet> pet(m, "Pet");

pet.def(py::init<const std::string &, Pet::Kind>())
    .def_readwrite("name", &Pet::name)
    .def_readwrite("type", &Pet::type);

py::enum_<Pet::Kind>(pet, "Kind")
    .value("Dog", Pet::Kind::Dog)
    .value("Cat", Pet::Kind::Cat)
    .export_values();
Run Code Online (Sandbox Code Playgroud)

我的情况不同。我有一个全局enum变量,它的值用于改变几个函数的行为。

enum ModeType {
  COMPLETE,
  PARTIAL,
  SPECIAL
};

std::vector<int> Munger(
  std::vector<int> &data,
  ModeType          mode
){
  //...
}
Run Code Online (Sandbox Code Playgroud)

我试图像这样注册它:

PYBIND11_MODULE(_mlib, m) {
  py::enum_<ModeType>(m, "ModeType")
    .value("COMPLETE", ModeType::COMPLETE )
    .value("PARTIAL",  ModeType::PARTIAL …
Run Code Online (Sandbox Code Playgroud)

enums c++11 pybind11

7
推荐指数
1
解决办法
3633
查看次数

pybind11,将 std::vector 转换为 py::list

根据 pybind11 文档https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html

当包含额外的头文件 pybind11/stl.h 时,std::vector<>/std::list<>/std::array<>、std::set<>/std::unordered_set<> 和 std::set<>/std::unordered_set<> 之间的转换自动启用 std::map<>/std::unordered_map<> 和 Python 列表、集合和字典数据结构。

但是,我终其一生都无法让它发挥作用。我想我误解了一些东西,所以我希望有人可以为我澄清。

这是我期望的工作:

// Test
std::vector<double> test_vec{1,2,3,4,5};
py::list test_list = test_vec;
py::list test_list2(test_vec);
py::list test_list3 = py::cast<py::list>(test_vec);
Run Code Online (Sandbox Code Playgroud)

以下是错误:

error: conversion from ‘std::vector<double>’ to non-scalar type ‘pybind11::list’ requested
    py::list test_list = test_vec;
error: no matching function for call to ‘pybind11::list::list(std::vector<double>&)’
    py::list test_list2(test_vec);
error: no matching function for call to ‘cast(std::vector<double>&)’
    py::list test_list3 = py::cast<py::list>(test_vec)
Run Code Online (Sandbox Code Playgroud)

文档说要查看tests/test_stl.cpp这应该如何工作的示例,但是我担心我无法破译该文件中发生的事情。

pybind11

7
推荐指数
1
解决办法
5892
查看次数

Pybind11 和 std::vector -- 如何使用胶囊释放数据?

我有一个返回 a 的 C++ 函数,std::vector并且使用 Pybind11,我想将该向量的内容作为 Numpy 数组返回,而不必将向量的基础数据复制到原始数据数组中。

当前尝试

这个写得很好的 SO 答案中,作者演示了如何确保在 Numpy 数组的引用计数为零时适当地释放在 C++ 中创建的原始数据数组。我尝试使用以下方法编写此版本std::vector

// aside - I made a templated version of the wrapper with which
// I create specific instances of in the PYBIND11_MODULE definitions:
//
//     m.def("my_func", &wrapper<int>, ...)
//     m.def("my_func", &wrapper<float>, ...)
// 
template <typename T>
py::array_t<T> wrapper(py::array_t<T> input) {
    auto proxy = input.template unchecked<1>();
    std::vector<T> result = compute_something_returns_vector(proxy);

    // give memory cleanup responsibility to the Numpy array …
Run Code Online (Sandbox Code Playgroud)

c++ python numpy c++11 pybind11

7
推荐指数
1
解决办法
2346
查看次数

使用 cmake 使用 cpp 和 cuda 源构建 pybind11 模块

我正在尝试为需要使用支持 cuda 的编译器进行编译的虚拟类生成 python 绑定。我正在使用 cmake 3.12.0、pybind11 v2.2.3 和 nvcc 7.5.17。编译失败,因为 和 等选项-flto直接-fno-fat-lto-objects传递给 nvcc,而 nvcc 无法识别它们。

这是一个(最小)示例:
Cuda 代码:

//Adder.hpp
#include <thrust/host_vector.h>
struct Adder {
    thrust::host_vector<float> a_h;
    thrust::host_vector<float> b_h;
    thrust::host_vector<float> r_h;
    int N;

    Adder(int N);
    void set_a(float const * const in);
    void set_b(float const * const in);
    void calc();
    void calc_gpu();
};

//Adder.cu
#include "Adder.hpp"
#include <thrust/device_vector.h>

Adder::Adder(int N): N(N),a_h(N),b_h(N),r_h(N) {}
void Adder::set_a(float const * const in) {
    for (int i=0; i<N; ++i) {
        a_h[i] = …
Run Code Online (Sandbox Code Playgroud)

cuda compiler-errors cmake nvcc pybind11

6
推荐指数
1
解决办法
4263
查看次数

如何apt安装python-pybind11?

我从我的项目文档中看到我需要python-pybind11使用安装

sudo apt -y install python-pybind11
Run Code Online (Sandbox Code Playgroud)

但我收到这样的错误:

正在阅读包裹清单...完成

构建依赖树
读取状态信息...完成

E:无法找到包 python-pybind11

我不确定python-pybind11包裹是否有效,在哪里可以检查?

apt ubuntu-16.04 pybind11

6
推荐指数
3
解决办法
3万
查看次数

如何使用 mingw-w64、Python 和 pybind11 手动构建 C++ 扩展?

我的最终目标是从我的 C++ 代码编译 Python C++ 扩展。目前,为了开始使用,我将遵循文档第一步中的一个简单示例pybind11。我的工作环境是 Windows 7 Professional 64 位、mingw-w64 (x86_64-8.1.0-posix-seh-rt_v6-rev0) 和 Anaconda3 with Python 3.7.4 64 位。我有2个文件。第一个是 C++ 文件——example.cpp

#include <pybind11/pybind11.h>

int add(int i, int j) {
    return i + j;
}

PYBIND11_MODULE(example, m) {
    m.doc() = "pybind11 example plugin"; // optional module docstring

    m.def("add", &add, "A function which adds two numbers");
}
Run Code Online (Sandbox Code Playgroud)

我使用以下命令编译 C++ 文件:


C:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/g++.exe -shared -std=c++11 -DMS_WIN64 -fPIC -ID:\Users\ADAS\anaconda3\Include -ID:\Users\ADAS\anaconda3\Library\include -ID:\Users\ADAS\anaconda3\pkgs\python-3.7.4-h5263a28_0\include -Wall -LD:\Users\ADAS\anaconda3\Lib -LD:\Users\ADAS\anaconda3\pkgs\python-3.7.4-h5263a28_0\libs example.cpp -o example.dll -lPython37

Run Code Online (Sandbox Code Playgroud)

编译结果成功,正在获取example.dll文件。

在下一步中,我运行以下 …

c++ python windows mingw-w64 pybind11

6
推荐指数
1
解决办法
2647
查看次数

如何在 Pybind11 中将 Python 字典转换为 C++ 对应部分?

目前我正在尝试将 a 转换py::dict为其对应的C++s std::map。尝试像这样使用自动转换失败:

#include <pybind11/stl.h>
namespace py = pybind11;
using namespace py::literals;
...
py::dict py_kwargs = py::dict("number1"_a = 5, "number2"_a = 42);
auto cpp_kwargs = py_kwargs.cast<std::map<int, int>>();

Run Code Online (Sandbox Code Playgroud)

但有一个例外:

Unable to cast Python instance of type <class 'dict'> to C++ type 'std::map<int,int,std::less<int>,std::allocator<std::pair<int const ,int> > >'
Run Code Online (Sandbox Code Playgroud)

我在这里缺少什么?

另外,我应该如何处理 python 字典具有不同键类型的情况,例如:

Unable to cast Python instance of type <class 'dict'> to C++ type 'std::map<int,int,std::less<int>,std::allocator<std::pair<int const ,int> > >'
Run Code Online (Sandbox Code Playgroud)

在这种情况下我应该如何进行转换?

c++ pybind11

6
推荐指数
1
解决办法
4318
查看次数

有人可以解释一下 pybind11 安装吗?

pybind11 文档总体来说不错,但它的一个方面不是解释安装过程以及使用 cmake 获取和运行示例的过程。

我已经设法弄清楚如何获取和构建示例。但这会带来更多问题。几乎所有示例都依赖于将 pybind11 存储库下载到示例文件夹中,并在 cmake 运行中包含存储库的根文件夹(根文件夹包含 cmakelists.txt 文件)。该存储库的内容与使用 pip 或 conda 安装 pybind11 时添加到 python 环境的内容有很多共同点。但文件夹组织完全不同。

所以我很好奇:

  • 为什么有区别?
  • 有没有一种方法可以使用环境安装中的内容,这样您就不必下载存储库来使用 cmake 构建示例?
  • 如果做不到这一点,将 pybind11 存储库放在一个公共位置的最佳方法是什么,这样就不必为了构建示例或为自己的代码提供重要的附加 cmake 功能而将其复制到各处?

一般来说,我对不理解这些事情的“如何运作”方面感到非常不舒服,所以这对我真的很有帮助。

c++ python cmake pybind11

6
推荐指数
1
解决办法
3092
查看次数

如何捆绑外部 CMake 依赖项来生成 Python 包?

我正在尝试为OpenVSlam项目生成 Python 绑定。

我正在使用 PyBind11 并遵循cmake_example模板。

我在我的开发环境中成功构建了该.so文件pybind11_add_module,其中安装了所有依赖项(例如 OpenCV、Protobuf 等库)。该.so文件在此开发环境中运行良好。我可以正确运行import sys; sys.path.append('.'); import openvslam_python;和使用绑定函数。但是,我想将该.so文件作为 Python 包发送。

问题是,当我运行python3 setup.py sdist bdist_wheel并尝试wheel在另一个环境(没有安装的依赖项)上安装结果时,它说找不到依赖项的.so文件。例如,它输出以下错误(在 Docker 容器中):

>>> import sys
>>> sys.path.append('.')
>>> import openvslam_python
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: libopenvslam.so: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)

我想知道是否有一种方法将 PyBind11 绑定的依赖项与 CMake(或者可能在脚本内setup.py)捆绑在一起,以便能够在没有安装任何依赖项的环境中安装它们。这样,我可以使用简单的pip install …

python cmake python-bindings pybind11

6
推荐指数
0
解决办法
315
查看次数