我想用 pybind11 构建简单的应用程序,pybind 已经使用 cmake (和 make install)安装在我的 Ubuntu 系统中。我使用这个简单的 cmake 文件:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(trt_cpp_loader )
find_package(pybind11 REQUIRED)
add_executable(trt_cpp_loader main.cpp)
set_property(TARGET trt_cpp_loader PROPERTY CXX_STANDARD 11)
这是main.cpp:
#include <iostream>
#include <pybind11/embed.h>
namespace py = pybind11;
using namespace std;
int main(){return 0;}
当我构建它时,我得到:
In file included from /usr/local/include/pybind11/pytypes.h:12:0,
                 from /usr/local/include/pybind11/cast.h:13,
                 from /usr/local/include/pybind11/attr.h:13,
                 from /usr/local/include/pybind11/pybind11.h:44,
                 from /usr/local/include/pybind11/embed.h:12,
                 from /home/stiv/lpr/trt_cpp_loader/main.cpp:2:
/usr/local/include/pybind11/detail/common.h:112:10: fatal error: Python.h: No such file or directory
 #include <Python.h>
          ^~~~~~~~~~
compilation terminated.
我该如何解决这个问题?(python-dev和python3-dev已经安装,Python.h可用)
我有一个带有 pybind11 嵌入式 python 解释器的 c++ 程序,执行以下 python 文件,它直接打印到std::cout
# test.py
print("text")
执行该文件的c++程序:
#include <pybind11/embed.h>
namespace py = pybind11;
int main() {
    py::scoped_interpreter guard{};
    py::eval_file("test.py");
}
我发现的其他解决方案需要修改 python 文件 - 如何将 python sys.stdout 作为 std::string 重定向到 c++,而不仅使用 print() 语句修改 python 代码?
(注:我已经在pybind11 的 GitHub上问过这个问题。为更广泛的受众提供支持。也标记 boost.python 以防有人有洞察力,但问题是如何使用 pybind11 做到这一点)
环境:Ubuntu 18.04、GCC 7.4.0、Python 3.6.9、pybind11 2.4.3
假设我们想用 pybind11 包装一个共享库libfoo.so,导出一个基类Foo(即,使用 vtable,在本例中只是一个虚拟析构函数)。
如果我们导出整个类(即添加visibility("default")到整个类),那么一切都会按预期进行:
CMakeLists.txt
cmake_minimum_required(VERSION 3.1.0)
add_subdirectory(pybind11)
add_library(foo SHARED foo.cpp)
set_target_properties(foo PROPERTIES CXX_VISIBILITY_PRESET hidden)
pybind11_add_module(pyfoo pyfoo.cpp)
target_link_libraries(pyfoo PRIVATE foo)
foo.h
#define FOO_API __attribute__((visibility("default")))
class FOO_API Foo { public: virtual ~Foo(); };
foo.cpp
#include "foo.h"
Foo::~Foo() {}
pyfoo.cpp
#include <pybind11/pybind11.h>
#include "foo.h"
PYBIND11_MODULE(pyfoo, m) {
    pybind11::class_<Foo>(m, "Foo")
        .def(pybind11::init<>());
}
测试.py
import pyfoo
f = pyfoo.Foo()
print("Test succeeded")
构建并运行: …
我正在使用 pybind11 将 C++ 函数公开给 Python 接口。我想包装重载的赋值运算符,但不知道如何。提供的文档和示例并没有真正涵盖它,至少从我所看到的来看是这样。
这是我正在尝试做的事情的简化版本:
class Num{
  public:
    Num(const double& num) : m_val(num), m_type(Num::Type::e_none){}
    Num& operator=(const double& rhs){m_val = rhs;}
  private:
    double m_val;
};
这是包装:
PYBIND11_MODULE(demo, m){
    py::class_<Num>(m, "Num")
        .def(py::init<const double&>())
        // Overloaded assignment operator binding ?
        ;
}
我主要关心的是在将 Num 分配给浮点数时保留它的数据类型。例如:
>>> m = Num(4.5)
>>> type(m)
<class 'demo.Num'>
>>> m = 5.5
>>> type(m)
<class 'float'>
这是我第一次使用 C++ 扩展和绑定,因此任何关于我应该做什么的见解都会很棒!
我已经在我的 Ubuntu 18.04.3 机器上安装了 pybind11 (几种不同的方式,包括 pip 和包管理器),但是当我尝试以推荐的方式指定包含文件时:
python3 -m pybind11 --includes
我收到此错误:
/usr/bin/python3: No module named pybind11.__main__; 'pybind11' is a package and cannot be directly executed
我发现这个错误的唯一地方是一个中文网页,它对解决问题没有帮助。如何让 pybind11 工作?
回答以下一些问题:
>>> import pybind11; print(pybind11.__file__)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'pybind11' has no attribute '__file__'
> python3 -m pip install pybind11
WARNING: The directory '/home/<username>/.cache/pip' or its parent directory is not owned or is not writable by the current user. The cache …我有成功运行的代码。其CmakeLists.txt是:
cmake_minimum_required(VERSION 3.15)
project(rotapro3)
set(CMAKE_CXX_STANDARD 14)
add_executable(rotapro3 main.cpp):
我想在这个项目中使用 pybind,并按照说明添加以下行:
add_subdirectory(pybind)
pybind11_add_module(rotapro3 main.cpp)
它成功启动,但我收到错误:
 add_executable cannot create target "rotapro3" because another target with
  the same name already exists.  The existing target is a module library
  created in source directory "C:/Users/Alex/Dropbox/rotapro3".
我对 CMake 几乎没有了解。我怎样才能重写这些行以允许我使用add_executable?
更新:
我还有另一个更复杂的情况:
    set(SOURCE_FILES
        unit_test/geometry/monomer_test.cpp
        unit_test/geometry/monomer_test.hpp
        unit_test/geometry/polymer_test.cpp
        unit_test/geometry/polymer_test.hpp
        unit_test/geometry/unit_box_test.cpp
        unit_test/geometry/unit_box_test.hpp
        unit_test/geometry/rect_shape_3d_test.cpp
        unit_test/geometry/rect_shape_3d_test.hpp
        src/general/guard.cpp
        src/general/guard.hpp
        src/general/fmt_enum.hpp
        src/general/string_format.cpp
        src/general/string_format.hpp
        src/geometry/monomer.cpp
        src/geometry/monomer.hpp
        src/geometry/polymer.cpp
        src/geometry/polymer.hpp
        src/geometry/unit_box.cpp
        src/geometry/unit_box.hpp
        src/geometry/rect_shape_3d.cpp
        src/geometry/rect_shape_3d.hpp
        )
include_directories(src/general)
include_directories(src/geometry)
include_directories(unit_test/general)
include_directories(unit_test/geometry)
add_executable(
        grapoli_lap ${SOURCE_FILES}
        unit_test/general/string_format_test.cpp
        unit_test/general/string_format_test.hpp …我正在尝试制作一个简单的示例,用 pybind 包装抽象 C++ 类。代码是:
\n#include <pybind11/pybind11.h>\n#include <ostream>\n#include <iostream>\nnamespace py = pybind11;\nusing namespace std;\n\nclass Base\n{\npublic:\n    virtual void test() = 0;\n\n};\nclass Derived: public Base\n{\npublic:\n    void test() {cout << "Test";}\n};\n\n\nPYBIND11_MODULE(example,m) {\n    py::class_<Base, Derived>(m, "Base")\n        .def(py::init<>())\n        .def("test", &Derived::test);\n}\n当我运行以下命令时
\nc++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` abstract_test.cpp -o example`python3-config --extension-suffix`\\n\n我收到错误:
\nIn file included from abstrakt_test.cpp:1:\n/home/anaconda3/envs/pybind/lib/python3.8/site-packages/pybind11/include/pybind11/pybind11.h: In instantiation of \xe2\x80\x98Return (Derived::* pybind11::method_adaptor(Return (Class::*)(Args ...)))(Args ...) [with Derived = Base; Return = void; Class = Derived; …这是我的函数签名
auto fun(py::array_t<double, py::array::c_style | py::array::forcecast> x)
问题是,当传递 array of 时np.float64,该数组不会被复制并且可以修改fun(这不是预期的),当传递 array ofnp.float32或其他数据类型时,它会被复制。
我的问题是,有没有办法强制复制,x即使它的 dtype 是np.float64.
我正在尝试使用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() << " …我正在尝试创建和分发(使用 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 存根?
pybind11 ×10
python ×8
c++ ×6
cmake ×2
ubuntu ×2
boost-python ×1
numpy ×1
python-3.x ×1
typeinfo ×1
vtable ×1