标签: pybind11

PyBind - 重载函数

首先,我要感谢大家努力解决我的这个疑问。我正在转换一个最小的 C++ 项目以在 Python 中使用。这种努力背后的真正原因是为了速度。

我遇到了 PyBind,对它的功能以及他们提供的文档数量感到非常惊讶。现在有一些事情阻止了工作,因为我不知道该怎么做。考虑文件“MySource.hpp”中的以下代码,您能告诉我如何完成绑定吗?

    struct Point3D  
    {
    public:
        double x, y, z;
        CPoint3D();
        CPoint3D(double x, double y, double z); 
        inline double Len() const;
        inline void Normalize();
    };

    Point3D VectorCross(const Point3D& pt1, const Point3D& pt2, const Point3D& pt3);
    void VectorCross(const float* u, const float* v, float * n);
Run Code Online (Sandbox Code Playgroud)

我能够将 Point3D 的绑定定义为一个类及其某些成员函数。但我不知道如何为重载方法“ VectorCross ”进行绑定。它有两种方法,一种接受 Point3D 的实例,另一种接受指向浮点数组的指针。

到目前为止我写的绑定如下所示

PYBIND11_MODULE(mymodule, m)
{
    py::class_<Point3D> point3d(m, "Point3D");
    point3d.def_readwrite("x", &CPoint3D::x);
    point3d.def_readwrite("y", &CPoint3D::y);
    point3d.def_readwrite("z", &CPoint3D::z);
    point3d.def(py::init<>());
    point3d.def(py::init<double , double , double >());
    point3d.def("Len", &CPoint3D::Len);
    point3d.def("Normalize", …
Run Code Online (Sandbox Code Playgroud)

swig boost-python cythonize pybind11

4
推荐指数
1
解决办法
4341
查看次数

通过 ExternalProject_Add 使用 pybind11 CMake 项目的智能方法

我正在写使用Python模块pybind11与CMake3.9.4。因为它是方便,我想下载pybind11源文件中使用ExternalProject_Add我的CMakeLists.txt。

当我运行时cmake .,它不下载pybind11源文件,并引发错误。

CMake Error at CMakeLists.txt:21 (add_subdirectory):
  The source directory
    /Users/me/foo/pybind11_external-prefix/src/pybind11_external
  does not contain a CMakeLists.txt file.

CMake Error at CMakeLists.txt:22 (pybind11_add_module):
  Unknown CMake command "pybind11_add_module".
Run Code Online (Sandbox Code Playgroud)

有一个解决方法:

  1. 注释掉 CMakeLists.txt 中的最后 3 行
  2. 跑 cmake .
  3. 运行make(然后,它下载pybind11源文件)
  4. 恢复 CMakeLists.txt 中的最后 3 行
  5. 跑 cmake .
  6. 跑 make

但是,这并不聪明......有没有办法下载pybind11使用ExternalProject_Add而不注释掉这些行并恢复它们(并且没有运行cmake和make两次)?

/Users/me/foo/CMakeLists.txt

cmake_minimum_required(VERSION 3.8)
project(foo)
set(CMAKE_CXX_STANDARD 14) …
Run Code Online (Sandbox Code Playgroud)

cmake pybind11

4
推荐指数
1
解决办法
3212
查看次数

使用 Python、C++ 和 pybind11 返回和传递原始 POD 指针(数组)

我有一个返回原始float指针的 C++ 函数和另一个接受原始float指针作为参数的C++ 函数。就像是:

float* ptr = something;
float* get_ptr(void) { return ptr; }
void use_ptr(float* ptr) { do_work(ptr); }
Run Code Online (Sandbox Code Playgroud)

我希望能够使用 Python 传递指针。像这样的东西:

import my_native_functions as native
ptr = native.get_ptr()
native.use_ptr(ptr)
Run Code Online (Sandbox Code Playgroud)

我正在使用 pybind11 创建我的本机 python 模块,但我不知道如何为该get_ptr()函数创建绑定。如果我只是执行以下操作:

PYBIND11_MODULE(my_native_functions, m)
{
    m.def("get_ptr", &get_ptr);
    m.def("use_ptr", &use_ptr);
}
Run Code Online (Sandbox Code Playgroud)

该get_ptr()函数返回一个 PythonFloat对象。我想这是有道理的,因为 python 中没有指针类型。但是,因为这现在是一个简单的Float,所以当我use_ptr()在 C/C++ 中调用函数并迭代指针时,只有数组的第一个元素是正确的。剩下的都是垃圾。为了解决这个问题,在 C++ 中,我必须将我的指针投射到/从std::size_t. 通过这样做,一切正常。

但是,我想问一下:是否有一种“正确的方法”可以在不std::size_t使用 pybind11进行转换的情况下实现上述目标?

如果你好奇我为什么这样做:我知道我所做的不是类型安全的。另外,我从不接触 Python 端的指针/整数。我只是从一个本机模块中检索它并将其传递给另一个。此外,我无法将指针转换为某种 numpy 视图,因为指针并不总是在 CPU 上。有时我想传递 …

c++ python pybind11

4
推荐指数
1
解决办法
3072
查看次数

`overload_cast` 在特定情况下失败

我发现了一个overload_cast失败的具体案例,我不知道如何解决这个问题。

显示该行为的最小示例是

#include <pybind11/pybind11.h>

// ----------------

template<class InputIterator, class OutputIterator>
void absolute(
  const InputIterator first, const InputIterator last, const OutputIterator result
)
{
  for ( auto it = first ; it != last ; ++it )
    *it = std::abs(*it);
}

// ----------------

std::vector<double> absolute(const std::vector<double> &in)
{
  std::vector<double> out = in;

  for ( auto &i: out )
    i = std::abs(i);

  return out;
}

// ----------------

namespace py = pybind11;

PYBIND11_MODULE(example,m)
{
  m.def("absolute", py::overload_cast<const std::vector<double>&>(&absolute));
}
Run Code Online (Sandbox Code Playgroud)

编译使用例如:

clang++ -O3 …
Run Code Online (Sandbox Code Playgroud)

c++ pybind11

4
推荐指数
1
解决办法
1130
查看次数

Pybind Numpy访问2D / ND阵列

pybind的新手-请阅读文档,但我不了解如何将其应用于2D阵列。

我有两个存储3D坐标的数组 shape = (10,3)

a = np.zeros(shape=(10,3))
b = np.ones(shape=(10,3)) * 3
c = a + b
Run Code Online (Sandbox Code Playgroud)

现在,使用pybind,如何在numpy数组上的C ++中执行此操作?

在某些文档中,我阅读了通过[]运算符访问元素的信息,而在另一些文档中,则阅读了()。如何分配3D向量?我如何获得指向数组元素的指针以使用跨度进行赋值-还是它有一个运算符?

python arrays numpy multidimensional-array pybind11

4
推荐指数
1
解决办法
3031
查看次数

如何在 Ubuntu 上导入使用 pybind11 创建的模块

我正在尝试设置一个 CMake 项目,在 Ubuntu 上使用 pybind11 为其 C++ 函数创建 python 绑定。

目录结构为:

pybind_test
    arithmetic.cpp
    arithmetic.h
    bindings.h
    CMakeLists.txt
    main.cpp
    pybind11 (github repo clone)
        Repo contents (https://github.com/pybind/pybind11)
Run Code Online (Sandbox Code Playgroud)

文件CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)
project(pybind_test)

set(CMAKE_CXX_STANDARD 17)

find_package(PythonLibs REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
include_directories(pybind11/include/pybind11)

add_executable(pybind_test main.cpp arithmetic.cpp)

add_subdirectory(pybind11)
pybind11_add_module(arithmetic arithmetic.cpp)

target_link_libraries(pybind_test ${PYTHON_LIBRARIES})
Run Code Online (Sandbox Code Playgroud)

arithmetic.cpython-36m-x86_64-linux-gnu.so存储库已成功构建并生成文件。如何将此共享对象文件导入到 python 中?

pybind11 文档中的文档有这一行

$ c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` example.cpp -o example`python3-config --extension-suffix`
Run Code Online (Sandbox Code Playgroud)

但我想使用 CMake 进行构建,并且我也不想每次运行 python 来使用此模块时都必须指定额外的包含目录。

我如何像普通的 python 模块一样将此共享对象文件导入到 python 中?

我使用的是 Ubuntu 16.04。

c++ python linux cmake pybind11

4
推荐指数
1
解决办法
1万
查看次数

Pybind:是否可以告知 Python 有关构造函数参数名称的信息?

在 Pybind 中,可以向 Python 告知函数参数的名称:

m.def("add", &add, "A function which adds two numbers",
  py::arg("i"), py::arg("j"));
Run Code Online (Sandbox Code Playgroud)

(http://pybind11.readthedocs.io/en/stable/basics.html#keyword-arguments)

构造函数有类似的东西吗?Spyder (Anaconda) 已经默认显示函数的输入参数,但对于构​​造函数,“帮助”仅显示:(*args, **kwargs)。

python constructor spyder anaconda pybind11

4
推荐指数
1
解决办法
2322
查看次数

适用于 STL 向量类的稳健型脚轮

我有一个与 STL 向量非常相似的类(差异对于 pybind11 类型caster 来说并不重要,所以我在这里忽略它们)。我为这门课编写了一个类型转换程序。下面给出了我的代码的最小工作示例。代码下方包含一个显示问题的示例。

问题是我的脚轮非常有限(因为我已经使用过py::array_t)。原则上,该接口确实接受元组、列表和 numpy 数组。但是,当我基于类型名重载时,接口对于输入的元组和列表失败(只是选择了第一个重载,即使它是不正确的类型)。

我的问题是:怎样才能让型脚轮更加坚固?是否有一种有效的方法可以尽可能多地为 STL 向量类重用现有的类型转换程序?

C++代码(包括pybind11接口)

#include <iostream>
#include <vector>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/numpy.h>

namespace py = pybind11;

// class definition
// ----------------

template<typename T>
class Vector
{
private:

  std::vector<T> mData;

public:

  Vector(){};
  Vector(size_t N) { mData.resize(N); };

  auto   data ()       { return mData.data (); };
  auto   data () const { return mData.data (); };
  auto   begin()       { return mData.begin(); };
  auto   begin() const { return mData.begin(); }; …
Run Code Online (Sandbox Code Playgroud)

pybind11

4
推荐指数
1
解决办法
915
查看次数

pybind11 从 C++ 修改 numpy 数组

编辑:它现在有效,我不知道为什么。不要以为我改变了什么

我想用pybind11传入并修改一个大的numpy数组。因为它很大,我想避免复制它并返回一个新的。

这是代码:

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/numpy.h>
#include <vector>

// C++ code
void calc_sum_cost(float* ptr, int N, int M, float* ptr_cost) {
  for(int32_t i = 1; i < N; i++) {
    for(int32_t j = 1; j < M; j++) {
      float upc = ptr[(i-1) * M + j];
      float leftc = ptr[i * M + j - 1];
      float diagc = ptr[(i-1) * M + j - 1];
      float transition_cost = std::min(upc, std::min(leftc, diagc));
      if (transition_cost == diagc) …
Run Code Online (Sandbox Code Playgroud)

python pybind11

4
推荐指数
1
解决办法
3282
查看次数

如何使用 buffer 协议为非平凡 (POD) 类实现 pybind11

我刚刚了解到Python Buffer Protocol,我想利用它从原始数据创建 pythonnumpy数组。C++我可以直接使用 pybind11 或 c++ python lib,但没有其他绑定生成器=/

阅读pybind11 文档并对其进行实验,我们似乎可以轻松地从简单的 C++ 结构(例如,std::vector<int>或struct具有普通旧数据类型,如int、float等)生成带有缓冲区协议的 python 绑定。然而,向更复杂的结构添加缓冲协议是不可能的,或者没有很好的记录。对于我的用例,我将 pybind a std::vector<struct Sequence>,Sequence定义如下:

struct Sequence {
    std::vector<float> feature;
    std::vector<int> label;
}
Run Code Online (Sandbox Code Playgroud)

一旦在 C++ 端实现了与缓冲区协议的 python 绑定,在 Python 端我可以做

for seq in vector_sequence:
   feature_data=numpy.array(seq.feature, copy=False)`
   label_data=numpy.array(seq.label, copy=False)`.
Run Code Online (Sandbox Code Playgroud)

在上面的循环中,vector_sequence是 C++ 的不透明绑定std::vector<Sequence>,并且seq是 a Sequence,它保存我想要用作numpy数组输入的两个向量,而无需将数据从 C++ 复制到 Python。

有谁知道 pybind11 …

c++ pybind11

4
推荐指数
1
解决办法
2635
查看次数