我有一个C++函数计算一个大张量,我想通过pybind11返回到Python作为NumPy数组.
从pybind11的文档来看,似乎使用STL unique_ptr是可取的.在下面的示例中,注释掉的版本有效,而给定的版本在运行时编译但失败("无法将函数返回值转换为Python类型!").
为什么smartpointer版本失败了?创建和返回NumPy数组的规范方法是什么?
PS:由于程序结构和数组的大小,不希望复制内存,而是从给定的指针创建数组.内存所有权应由Python采用.
typedef typename py::array_t<double, py::array::c_style | py::array::forcecast> py_cdarray_t;
// py_cd_array_t _test()
std::unique_ptr<py_cdarray_t> _test()
{
double * memory = new double[3]; memory[0] = 11; memory[1] = 12; memory[2] = 13;
py::buffer_info bufinfo (
memory, // pointer to memory buffer
sizeof(double), // size of underlying scalar type
py::format_descriptor<double>::format(), // python struct-style format descriptor
1, // number of dimensions
{ 3 }, // buffer dimensions
{ sizeof(double) } // strides (in bytes) for each index …Run Code Online (Sandbox Code Playgroud) 我正在尝试遵循本页上找到的使用 pybind11 在 c++ 中嵌入 python 的简单示例。但是,当尝试使用 cmake 构建解决方案时,我不断收到一条错误消息:
通过不在 CMAKE_MODULE_PATH 中提供“Findpybind11.cmake”,该项目要求 CMake 查找“pybind11”提供的包配置文件,但 CMake 没有找到。
找不到“pybind11”提供的具有以下任何名称的包配置文件:
Run Code Online (Sandbox Code Playgroud)pybind11Config.cmake pybind11-config.cmake
我的桌面上有一个名为 pybindtest 的文件夹,其中包括上面链接中所述的 CMakeLists.txt 和 main.cpp,以及我创建的构建文件夹。在构建文件夹中,我尝试了以下几行但无济于事(在 Powershell 7 上运行):
cmake ..
cmake .. -Dpybind11_DIR=C:/Users/ben.wolfley/Anaconda3/Library/share/cmake/pybind11/pybind11Config.cmake
cmake .. -DCMAKE_MODULE_PATH=C:/Users/ben.wolfley/Anaconda3/Library/share/cmake/pybind11
Run Code Online (Sandbox Code Playgroud)
我使用安装了 pybind11 conda install pybind11,并且 pybind11Config.cmake 位于C:\Users\ben.wolfley\Anaconda3\Library\share\cmake\pybind11
我有以下目录布局
awesome_package
\- module1.py
\- build
\- module2.so
Run Code Online (Sandbox Code Playgroud)
我目前导入module1为
import awesome_package.module1
Run Code Online (Sandbox Code Playgroud)
和module2为
import sys
sys.path.append('path/to/awesome_package/build')
import module2
Run Code Online (Sandbox Code Playgroud)
但我希望能够使用以前的语法.
module2由pybind11以如下方式创建:
PYBIND11_MODULE(module2, module2) {
module2.doc() = "C++ module wrapped for Python";
module2.def("some_cpp_function", some_cpp_function)
}
Run Code Online (Sandbox Code Playgroud) 我们在python中有一个代码库,它使用asyncio和协同例程(async方法和awaits),我想做的是从C++类中调用其中一个方法,这个类被拉入python(使用pybind11)
假设有这样的代码:
class Foo:
async def bar(a, b, c):
# some stuff
return c * a
Run Code Online (Sandbox Code Playgroud)
假设代码是从python中调用的,并且有一个io循环处理它,在某些时候,代码会进入bar需要调用此方法的C++领域- 如何await在C++中实现这一结果?
考虑这个小 pybind11 包装器 + 测试:
安装程序.py
from pybind11.setup_helpers import Pybind11Extension
from pybind11.setup_helpers import build_ext
from setuptools import setup
setup(
name="wrapper",
ext_modules=[Pybind11Extension("wrapper", ["wrapper.cpp"])],
cmdclass={"build_ext": build_ext},
)
Run Code Online (Sandbox Code Playgroud)
包装器.cpp
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <vector>
namespace py = pybind11;
struct Mesh2d {
public:
Mesh2d(int numVerts, int numTris)
: numVertices(numVerts), numTriangles(numTris) {
vertices = new float[numVerts * 2];
indices = new int[numTris * 3];
}
~Mesh2d() {
delete vertices;
delete indices;
}
void makeVertex(int i, float x, float y) {
vertices[i * 2 + …Run Code Online (Sandbox Code Playgroud) PyGILState_Ensure()pybind11 是否以某种方式神奇地完成了和的工作PyGILState_Release()?如果没有,我该怎么做?
关于使用 pybind11 将 python 函数作为回调传递给 C++有 很多 问题,但我还没有找到一个解释如何使用 pybind11 的 GIL 的问题。
\n文档中关于 GIL 的说明非常清楚:
\n\n\n[...] 但是,当从 C 创建线程时(例如由具有自己的线程管理的第三方库),它们不\xe2\x80\x99t 保存 GIL,也不存在它们的线程状态结构。
\n如果您需要从这些线程调用Python代码(通常这将是上述第三方库提供的回调API的一部分),您必须首先通过创建线程状态数据结构向解释器注册这些线程,然后获取GIL,最后存储它们的线程状态指针,然后才能开始使用 Python/C API。
\n
我可以轻松绑定一个需要回调的 C++ 函数:
\npy::class_<SomeApi> some_api(m, "SomeApi"); \nsome_api\n .def(py::init<>())\n .def("mode", &SomeApi::subscribe_mode, "Subscribe to \'mode\' updates.");\nRun Code Online (Sandbox Code Playgroud)\n相应的 C++ 函数类似于:
\nvoid subscribe_mode(const std::function<void(Mode mode)>& mode_callback);\nRun Code Online (Sandbox Code Playgroud)\n但是因为 pybind11 无法了解我的 C++ 实现中发生的线程,所以我认为它无法为我处理 GIL。因此,如果mode_callback由从 C++ 创建的线程调用,这是否意味着我应该为每个调用编写一个包装SomeApi::subscribe_mode器? …
我有一些用c ++编写的代码,我试图在python中使用而不再重写python中的完整代码,我使用Pybind11为它构建一个python模块.我试图通过以下教程在Microsoft Visual Studio 2015中实现此功能https://pybind11.readthedocs.io/en/stable/basics.html
我在视觉工作室做了一些事情.1)从https://codeload.github.com/pybind/pybind11/zip/master下载了Pybind11
2)解压缩文件
3)在visual studio中,启动了一个新的空C++项目.
4)在VC++目录> include目录中添加了我的python解释器include文件夹(C:/ python27/include)和Pybind11(C:/ Pybind11/include)
5)在链接器>输入>附加依赖项中添加了其他依赖项(C:\ Python27\libs\python27.lib)
6)要在Python中使用输出文件,我需要一个.pyd文件,所以我在这里修改了配置属性>常规>目标扩展:.pyd
7)将项目默认值>配置类型更改为动态库(.dll)
所以我能够构建我的项目并生成.pyd文件但是在导入这个模块时我收到以下错误:ImportError:动态模块没有定义init函数(initProject11)
我搜索了这个错误并得到了这个链接http://pybind11.readthedocs.io/en/stable/faq.html 但我找不到我的解决方案.
所以我正在寻找上述问题的解决方案.非常感谢提前.
这是我的CPP文件代码
#include <pybind11/pybind11.h>
int add(int i, int j) {
return i + j;
}
namespace py = pybind11;
PYBIND11_PLUGIN(example) {
py::module m("example", "pybind11 example plugin");
m.def("add", &add, "A function which adds two numbers");
return m.ptr();
}
Run Code Online (Sandbox Code Playgroud) 我试图使用pybind11包装一个c ++库,所以我可以在Python 3.x中使用它.
我尝试使用swig包装代码,但我遇到了一个问题,SWIG会生成cxx文件,但不会读取我引用的头文件,所以有人建议我使用pybind11因为它比swig更好(这是意见我知道),但我无法找到有关如何引用/构建项目的资源.
我的环境是:
当我为Swig创建我的界面文件时,我可以做一些简单的事情:
```
%module filegdbapi
%{
#include "FileGDBAPI.h"
%}
%include "FileGDBAPI.h"
Run Code Online (Sandbox Code Playgroud)
```
然后在swig构建中,我可以引用-I.h文件的位置.
我如何在pybind11中做这样的事情?这么简单吗?
当你有.cpp文件时,pybind11的文档总是显示构建包装器.我可以用一种方法来使用pybind11,我可以用swig构建一个包装器吗?如果是这样,你如何设置文件?
有人能指出我只是从现有的c ++代码生成python包装器的项目吗?
谢谢
我很好奇最灵活,最有效,最无缝的方法是让C++和Python相互通信.竞争者似乎是Pybind11,Boost.Python,两者都没有(只需编写函数和包装器,如下所示).
using namespace boost::algorithm;
static PyObject* strtest(PyObject* self, PyObject* args)
{
std::string s = "Boost C++ Libraries";
to_upper(s);
PyObject * python_val = Py_BuildValue("s", s.c_str());
return python_val;
}
PyMODINIT_FUNC initmath_demo(void)
{
static PyMethodDef methods[] = {
"Test boost libraries" },
{ NULL, NULL, 0, NULL }
};
PyObject *m = Py_InitModule("math_demo", methods);
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用包装我的C++代码pybind11.在C++中,我有一个Matrix3D充当三维数组(即形状[n,m,p])的类.它具有以下基本签名:
template <class T> class Matrix3D
{
public:
std::vector<T> data;
std::vector<size_t> shape;
std::vector<size_t> strides;
Matrix3D<T>();
Matrix3D<T>(std::vector<size_t>);
Matrix3D<T>(const Matrix3D<T>&);
T& operator() (int,int,int);
};
Run Code Online (Sandbox Code Playgroud)
为了最小化包装器代码,我想将此类直接转换为NumPy数组(副本没有问题).例如,我想直接包装以下签名的函数:
Matrix3D<double> func ( const Matrix3D<double>& );
Run Code Online (Sandbox Code Playgroud)
使用包装器代码
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/numpy.h>
namespace py = pybind11;
PYBIND11_PLUGIN(example) {
py::module m("example", "Module description");
m.def("func", &func, "Function description" );
return m.ptr();
}
Run Code Online (Sandbox Code Playgroud)
目前我还有另一个接受和返回的功能py::array_t<double>.但我想避免为每个函数编写一个包装函数,方法是用一些模板替换它.
这已经为Eigen-library(对于数组和(2-D)矩阵)完成.但是代码对我来说太过牵扯,无法从中派生自己的代码.另外,我真的只需要包装一个简单的类.