首先,我要感谢大家努力解决我的这个疑问。我正在转换一个最小的 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) 我正在写使用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)
有一个解决方法:
cmake .make(然后,它下载pybind11源文件)cmake .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) 我有一个返回原始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 上。有时我想传递 …
我发现了一个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) 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向量?我如何获得指向数组元素的指针以使用跨度进行赋值-还是它有一个运算符?
我正在尝试设置一个 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。
在 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)。
我有一个与 STL 向量非常相似的类(差异对于 pybind11 类型caster 来说并不重要,所以我在这里忽略它们)。我为这门课编写了一个类型转换程序。下面给出了我的代码的最小工作示例。代码下方包含一个显示问题的示例。
问题是我的脚轮非常有限(因为我已经使用过py::array_t)。原则上,该接口确实接受元组、列表和 numpy 数组。但是,当我基于类型名重载时,接口对于输入的元组和列表失败(只是选择了第一个重载,即使它是不正确的类型)。
我的问题是:怎样才能让型脚轮更加坚固?是否有一种有效的方法可以尽可能多地为 STL 向量类重用现有的类型转换程序?
#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传入并修改一个大的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 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 …