我正在尝试使用包装我的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)矩阵)完成.但是代码对我来说太过牵扯,无法从中派生自己的代码.另外,我真的只需要包装一个简单的类.
我正在尝试使用CMake和pybind 11将现有的Python代码和新的C++ 11代码打包在一起.我认为我遗漏了一些简单的东西添加到CMake脚本中,但无法在任何地方找到它:pybind11示例只有C++代码和没有Python,其他在线资源相当复杂而且不是最新的 - 所以我无法弄清楚如何将两种语言的函数打包在一起并通过Python提供它们import my_package......作为一个例子,我已经克隆了pybind11的cmake_example并增加了MULT功能成cmake_example/mult.py
def mult(a, b):
return a * b
Run Code Online (Sandbox Code Playgroud)
我如何将其与下面的测试一起显示add并subtract通过测试?
import cmake_example as m
assert m.__version__ == '0.0.1'
assert m.add(1, 2) == 3
assert m.subtract(1, 2) == -1
assert m.mult(2, 2) == 4
Run Code Online (Sandbox Code Playgroud)
目前,这个测试失败了..
谢谢!
我希望能够将我的 C++ 代码作为 python 包调用。为此,我使用pybind11CMakelists (遵循此示例https://github.com/pybind/cmake_example)。我的问题是我必须在代码编译中包含 GSL 库,并且这些库需要显式链接器 -lgsl。
如果我只是编译并运行 C++,而不用 python 包装它,则以下 Cmakelists.txt 文件可以完成这项工作
cmake_minimum_required(VERSION 3.0)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
project(myProject)
add_executable(
myexecutable
main.cpp
function1.cpp
)
find_package(GSL REQUIRED)
target_link_libraries(myexecutable GSL::gsl GSL::gslcblas)
Run Code Online (Sandbox Code Playgroud)
但当使用pybind11模板时,我发现不允许,add_executable因此 target_link_libraries不起作用。
我已经尝试过这个
project(myProject)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED YES) # See below (1)
# Set source directory
set(SOURCE_DIR "project")
# Tell CMake that headers are also in SOURCE_DIR
include_directories(${SOURCE_DIR})
set(SOURCES "${SOURCE_DIR}/functions.cpp")
# Generate Python module
add_subdirectory(lib/pybind11)
pybind11_add_module(namr ${SOURCES} …Run Code Online (Sandbox Code Playgroud) 我设计了一个 C++ 系统,它从在单独线程中运行的过程调用用户定义的回调。简化后system.hpp如下所示:
#pragma once
#include <atomic>
#include <chrono>
#include <functional>
#include <thread>
class System
{
public:
using Callback = std::function<void(int)>;
System(): t_(), cb_(), stop_(true) {}
~System()
{
stop();
}
bool start()
{
if (t_.joinable()) return false;
stop_ = false;
t_ = std::thread([this]()
{
while (!stop_)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (cb_) cb_(1234);
}
});
return true;
}
bool stop()
{
if (!t_.joinable()) return false;
stop_ = true;
t_.join();
return true;
}
bool registerCallback(Callback cb)
{
if (t_.joinable()) return false; …Run Code Online (Sandbox Code Playgroud) pybind11 是否无缝适用于 C++14 和 C++17?
我计划在我的项目中使用 Boost.python,该项目目前使用 C++11。将来我可能必须升级到 C++14 或 C++17。所以我想了解这里的正确选择是什么 - boost.python 或 pybind11。
从 pybind11 文档中,它说 - “C++11 和 Python 之间的无缝可操作性”所以有点困惑
我有一个 C++ 中的单例类(没有公共构造函数,C++ 程序员调用 class.instance() 来创建单例或返回现有的单例)。
我更愿意在 Python 级别隐藏它。如果我正在编写一个 Python 单例,我会在__new__. 如果一个类没有公共构造函数,我认为我无法创建__init__包装器(我的尝试失败了)。我在 pybind11 文档中没有看到提及__new__(尽管可能错过了它,并且 Google 似乎很乐意省略下划线包含“new”的返回页面,但没有提及__new__)。
pybind11(甚至Boost.Python)有单例配方吗?
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) 根据 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这应该如何工作的示例,但是我担心我无法破译该文件中发生的事情。
我有一个返回 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++ 库,我试图使用 pybind11 公开它。我在正确设置包含路径时遇到问题。
项目目录结构如下:
root
- sub-project-1
-> C++ files that know nothing about python.
- sub-project-2
-> more C++ files
-> sub-sub-project
-> even more C++ files
- sub-project-3
-> et cetera
- Interfaces
-> R
-> R interface stuff
-> python
-> package_name
-> setup.py
-> pybind11_bindings.cpp
Run Code Online (Sandbox Code Playgroud)
setup.py 文件当前如下所示。该结构主要是从 pybind11 文档复制的。
from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext
import sys
import setuptools
from glob import glob
__version__ = '0.0.1'
class get_pybind_include(object):
"""Helper class to …Run Code Online (Sandbox Code Playgroud)