标签: pybind11

在 python 中使用 C++ 对象与 pybind11

我的main.cpp文件如下所示:

// Embeding the interpreter into c++
// https://pybind11.readthedocs.io/en/master/advanced/embedding.html


#include <pybind11/embed.h>
#include <iostream>
#include <string>

// Define namespace for pybind11
namespace py = pybind11;

class Vehiclee
{ 
    // Access specifier 
    public: 

    // Data Members 
    int vehicle_id;
    std::string vehicle_name; 
    std::string vehicle_color;

    // Member Functions() 
    void printname() 
    { 
       std::cout << "Vehicle id is: " << vehicle_id; 
       std::cout << "Vehicle name is: " << vehicle_name; 
       std::cout << "Vehicle color is: " << vehicle_color; 
    } 
}; 


int main() {
    // Initialize the …
Run Code Online (Sandbox Code Playgroud)

c++ python pybind11

5
推荐指数
1
解决办法
6463
查看次数

使用 pybind11 在多线程 C++ 程序中嵌入 Python 解释器

我正在尝试使用pybind11以使第三方 C++ 库调用 Python 方法。该库是多线程的,每个线程创建一个 Python 对象,然后对该对象的方法进行多次调用。

我的问题是调用py::gil_scoped_acquire acquire;死锁。下面给出了重现该问题的最小代码。我究竟做错了什么?

// main.cpp
class Wrapper
{
public:
  Wrapper()
  {
    py::gil_scoped_acquire acquire;
    auto obj = py::module::import("main").attr("PythonClass")();
    _get_x = obj.attr("get_x");
    _set_x = obj.attr("set_x");
  }
  
  int get_x() 
  {
    py::gil_scoped_acquire acquire;
    return _get_x().cast<int>();
  }

  void set_x(int x)
  {
    py::gil_scoped_acquire acquire;
    _set_x(x);
  }

private:
  py::object _get_x;
  py::object _set_x;
};


void thread_func()
{
  Wrapper w;

  for (int i = 0; i < 10; i++)
  {
    w.set_x(i);
    std::cout << "thread: " << std::this_thread::get_id() << " …
Run Code Online (Sandbox Code Playgroud)

c++ python multithreading pybind11

5
推荐指数
1
解决办法
2557
查看次数

如何使用存根构建和分发 Pybind11 扩展?

我正在尝试创建和分发(使用 pip)一个 Python 包,其中包含 Python 代码和使用 Pybind11(使用 Visual Studio 2019)编译为 .pyd 文件的 C++ 代码。我还想包含.pyi 存根文件,用于 VScode 和其他编辑器。我找不到太多关于正确执行此操作的文档。

希望能够像平常一样通过 pip 安装包,并from mymodule.mysubmodule import myfunc像普通的 Python 包一样编写等,包括使用我编写的 .pyi 文件自动完成、类型注释、VScode 智能感知等。

我的 C++ 代码位于多个 cpp 和头文件中。它使用一些标准库一些外部库(例如boost)。它定义了一个模块和 2 个子模块。我希望能够在 Windows 和 Linux 上以及 x86 和 x64 上分发它。我目前的目标是 Python 3.9 和 c++17 标准。

我应该如何构建和分发这个包?我是否包含 c++ 源文件,并创建一个类似于Pybind11 示例的 setup.py ?如果是这样,我如何包含外部库?如何构建 .pyi 存根文件?这是否意味着尝试安装我的软件包的人也需要 C++ 编译器?

或者,我应该将我的 c++ 编译为每个平台和架构的 .pyd/.so 文件吗?如果是这样,有没有办法指定通过 pip 安装哪个?再说一次,我将如何构建 .pyi 存根?

c++ python python-extensions pybind11

5
推荐指数
1
解决办法
4215
查看次数

使用 C++ 扩展制作跨平台 PyPI 包(用 pybind11 包装,用 bazel 构建)

我有一个混合 C++/Python 项目。它使用pybind11包装 Python 的 C++ 代码,并使用 bazel来构建解决方案。我对这个技术栈非常满意。安装 C++ 编译器、Python 发行版和 bazel 后,bazel run命令即可下载依赖项、构建并运行整个 C++/absl/Python/numpy 集团。

但为了让用户的事情变得更简单,我想将我的代码打包为 PyPI 包,以便可以使用pip install. 我希望该包是跨平台的,可以在 Windows、Linux 和 MacOS 上运行。

在生成新版本时,建立构建、打包并将所有内容上传到 PyPI 的管道的最清晰方法是什么?

pip pypi bazel pybind11

5
推荐指数
1
解决办法
623
查看次数

pybind11:枚举与枚举类?

我理解 C++ 上下文中枚举和枚举类之间的区别,但是在绑定枚举和枚举类的上下文中是否有任何真正的区别?

举例来说:

enum class options {
  maybe,
  yes,
  no,
};

enum words {
   hello,
   world
};
Run Code Online (Sandbox Code Playgroud)

我刚刚以相同的方式绑定它们(见下文),所以我的问题是,我是否忽略了某些东西,或者在使用 pybind11 将它们绑定到 python 的上下文中,枚举和枚举类实际上是相同的吗?

py::enum_<options>(m, "options")
    .value("maybe", options::maybe)
    .value("yes", options::yes)
    .value("no", options::no);

py::enum_<words>(m, "words")
    .value("hello", words::hello)
    .value("world", words::world)
Run Code Online (Sandbox Code Playgroud)

c++ python enums pybind11

5
推荐指数
1
解决办法
4540
查看次数

使用 pybind11 在 C++ 之间传递 Python 大整数(&gt;256 位)

我正在为基于 C++ 的加密方案开发一个 python 包装器,其中密钥和密文是非常大的数字(最多 2048 位)。

在 C++ 中,我使用Intel BigNumber 类来存储和处理如此大的数字。

由于 Python 本身支持通过对象“看似”无限位整数,因此我在通过 Python 将此类变量作为参数传递时遇到了麻烦。

  py::class_<BigNumber>(m, "BigNumber")
      .def(py::init<unsigned int>())
      .def(py::init<int>())
      .def(py::init<BigNumber>())
      .def(py::init([](py::list data) {
        size_t length = data.size();
        unsigned int* pData = new unsigned int[length];
        for (int i = 0; i < length; i++) {
          pData[i] = data[i].cast<unsigned int>();
        }
        return std::unique_ptr<BigNumber>(new BigNumber(pData, length));
      }))
      .def(py::init([](py::array_t<unsigned int> data) {
        py::buffer_info buffer_info = data.request();

        unsigned int* pData = static_cast<unsigned int*>(buffer_info.ptr);
        std::vector<ssize_t> shape = buffer_info.shape;
        return std::unique_ptr<BigNumber>(new BigNumber(pData, …
Run Code Online (Sandbox Code Playgroud)

c++ python bignum pybind11

5
推荐指数
1
解决办法
615
查看次数

pybind11implicitly_convertible 不起作用

我正在努力使最简单的示例发挥作用。这是我的代码:

// example.cpp

#include <pybind11/pybind11.h>
namespace py = pybind11;

class B {
public:
    int b;
};

class A {
public:
    int a;
    A(int a) :a(a) {}
    A(B b) { a = b.b; }
};

void fn(A) {}

PYBIND11_MODULE(example, m) {

    py::class_<A>(m, "A")
        .def(
            py::init<int>(),
            py::arg("a") = 1
        );

    py::class_<B>(m, "B")
        .def(
            py::init<int>(),
            py::arg("b") = 2
        );

    py::implicitly_convertible<A, B>();

    m.def("fn", &fn,
        py::arg("a")
    );
}
Run Code Online (Sandbox Code Playgroud)
# test.py

from example import *

a = A()
b = B()

fn(b)
Run Code Online (Sandbox Code Playgroud)

它构建得很好,但输出是:

$ python3.9 test.py …
Run Code Online (Sandbox Code Playgroud)

implicit-conversion pybind11

5
推荐指数
1
解决办法
916
查看次数

.so 似乎由于 pybind11 参数而未导出 C++ 函数

我目前正在尝试定义一个共享库,我的目标是从 Python C++ 扩展以及普通 C++ 应用程序中使用它。

我设法构建了共享库,并尝试将一个简单的 C++ 应用程序链接到它以测试其功能,但共享库的函数之一被链接器视为未定义的引用。检查后nm --demangle --dynamic --defined-only --extern-only libmylib.so,我意识到该函数没有被共享库导出,但我不知道为什么。

该函数的签名如下:

void bootstrap_mylib(std::vector<std::string> python_path,
        std::vector<std::string> python_scripts,
        std::string interface_module,
        std::function<void (pybind11::module_, pybind11::object)> interface_module_initializer);
Run Code Online (Sandbox Code Playgroud)

如果我注释掉最后一个参数,一切都会顺利,所以问题似乎来自于我以某种方式声明与 pybind11 的依赖关系的方式。

以下是我的 CMakeLists.txt 的相关部分:

set(CMAKE_CXX_COMPILER /usr/bin/g++)

project(monilog LANGUAGES CXX VERSION 0.0.1)

set(PYBIND11_PYTHON_VERSION 3.8)
find_package(pybind11 REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})

add_library(mylib SHARED MyLib.cc MyLib.h)
set_property(TARGET mylib PROPERTY CXX_STANDARD 17)

target_link_libraries(mylib ${PYTHON_LIBRARIES})

set_target_properties(mylib PROPERTIES VERSION ${PROJECT_VERSION})
set_target_properties(mylib PROPERTIES SOVERSION 1)
set_target_properties(mylib PROPERTIES PUBLIC_HEADER MyLib.h)
Run Code Online (Sandbox Code Playgroud)

知道我可能做错了什么吗?

编辑:最小工作示例

这是我的问题的一个最小示例,包含以下文件:

example.h

#include <pybind11/stl.h>

namespace Example
{
    void simple_func(std::string …
Run Code Online (Sandbox Code Playgroud)

c++ cmake shared-libraries pybind11

5
推荐指数
1
解决办法
137
查看次数

Python/pip:如何使用扩展模块进行可编辑包安装?

我正在开发一个带有 C++ 扩展模块的 python 包,该模块通过 pybind11 与 python 代码进行互操作,并且我正在使用 CMake 构建该包(基于答案)。

我已将软件包安装为可编辑,以帮助开发pip install -e .

我经常更新 C++ 扩展模块,每次这样做时,让我的更改生效的唯一方法是完全清理每个构建文件,卸载,然后重新安装包,这在很大程度上违背了拥有一个包的目的。用于开发目的的可编辑安装。

有没有一种方法可以使用扩展模块进行可编辑安装,以便我可以在对其进行更改时重建模块,而无需每次都清理并重新安装整个包?

python pip cmake extension-modules pybind11

5
推荐指数
0
解决办法
244
查看次数

在包含 pybind11 包装的 C++ 的 python 代码上运行 santizer(ubsan、asan 等)

我维护一个大型 C++ 库,我使用 pybind11 部分接触了 python。C++ 库包含单元测试,我有时会在各种清理程序下运行这些测试:asan、tsan 等。这些测试运行干净,但当然测试并不完美,您无法 100% 测试所有边缘情况。

当我使用具有特定设置、特定数据集和各种选项的库时,有一个特定的 jupyter 笔记本会崩溃,这些选项可以在纯 C++ 环境中复制,但这种复制将非常耗费人力、时间并且容易出错。

如果我面前有纯 C++,我会通过 ubsan、asan 等运行笔记本,以确保我没有看到未定义的行为或段错误。有没有办法可以将这些消毒剂(或类似的东西)应用到我的笔记本上,而无需用原始 C++ 重写所有 python 胶水?

c++ python address-sanitizer ubsan pybind11

5
推荐指数
0
解决办法
472
查看次数