我正在尝试为OpenVSlam项目生成 Python 绑定。
我正在使用 PyBind11 并遵循cmake_example模板。
我在我的开发环境中成功构建了该.so文件pybind11_add_module,其中安装了所有依赖项(例如 OpenCV、Protobuf 等库)。该.so文件在此开发环境中运行良好。我可以正确运行import sys; sys.path.append('.'); import openvslam_python;和使用绑定函数。但是,我想将该.so文件作为 Python 包发送。
问题是,当我运行python3 setup.py sdist bdist_wheel并尝试wheel在另一个环境(没有安装的依赖项)上安装结果时,它说找不到依赖项的.so文件。例如,它输出以下错误(在 Docker 容器中):
>>> import sys
>>> sys.path.append('.')
>>> import openvslam_python
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: libopenvslam.so: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我想知道是否有一种方法将 PyBind11 绑定的依赖项与 CMake(或者可能在脚本内setup.py)捆绑在一起,以便能够在没有安装任何依赖项的环境中安装它们。这样,我可以使用简单的pip install …
我无法理解如何使用 pybind11 conan 包。我可以使用其他一些,但 pybind11 给我带来了困难。
我的出发点是这样的:
柯南文件.txt:
[requires]
pybind11/2.7.1
[generators]
cmake
Run Code Online (Sandbox Code Playgroud)
主要.cpp:
[requires]
pybind11/2.7.1
[generators]
cmake
Run Code Online (Sandbox Code Playgroud)
CMakeLists.txt
cmake_minimum_required(VERSION 3.21)
project(cobind11 VERSION 1.0 LANGUAGES CXX)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
pybind11_add_module(cobind main.cpp)
Run Code Online (Sandbox Code Playgroud)
我试图让这项工作成功的痛苦日志:
初始点
如果我尝试按照上面的方式构建项目,我会收到以下错误:
CMake Error at CMakeLists.txt:10 (pybind11_add_module):
Unknown CMake command "pybind11_add_module".
-- Configuring incomplete, errors occurred!
Run Code Online (Sandbox Code Playgroud)
添加find_package(需要pybind11)
如果我添加一行,find_package(pybind11 REQUIRED)我会收到以下错误:
CMake Error at CMakeLists.txt:16 (find_package):
By not providing "Findpybind11.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "pybind11",
but CMake did not …Run Code Online (Sandbox Code Playgroud) 使用pybind11 ,如何使用NumPy公开 POD 结构数组,同时让它们向用户显示为漂亮的 Python 对象?
我使用pybind11向Python公开C 风格 API。有一些类型在 C 中实现为简单的 POD 结构,在 Python 中作为不透明对象更有意义。pybind11允许我做到这一点并定义对象在 Python 中的样子。
我还想公开一个动态分配的数组。使用pybind11和NumPy这样做 是可能的,但我还没有找到一种与我已经公开类型本身的方式兼容的方法。
我最终得到了两种不同的 Python 类型,尽管底层的 C 类型是相同的,但它们彼此不兼容。
我正在寻找一种不涉及不必要副本的解决方案。由于所有数据都是 POD,我认为应该可以将数据重新解释为 C 端的结构或 Python 端的不透明对象。
C API 是固定的,但我可以自由地设计 Python API。
在 C/C++ 方面,类型如下所示:
struct apiprefix_opaque_type
{
int inner_value;
};
Run Code Online (Sandbox Code Playgroud)
使用pybind11,我将结构公开为不透明对象。不暴露并不重要inner_value,但它对用户来说根本没有太大价值,拥有更高级别的类型更有意义。
namespace py = pybind11;
void bindings(py::module_& m)
{
py::class_<apiprefix_opaque_type>(m, "opaque_type")
.def(py::init([]() { …Run Code Online (Sandbox Code Playgroud) 我正在将 C++ 库与越来越流行的pybind11连接起来,以获得本机 Python 绑定;配置是通过CMake.
我的CMakeLists.txt样子
cmake_minimum_required(VERSION 3.0)
project(foo)
FILE(GLOB foo_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
FIND_PACKAGE(pybind11 REQUIRED)
pybind11_add_module(mylib ${foo_SRCS})
Run Code Online (Sandbox Code Playgroud)
然而,这似乎没有注册安装规则。因此,虽然构建树中的一切都按预期工作,但make install没有执行任何操作。
需要添加什么才能按顺序安装?
我有一个与此非常相似的结构:
struct data_point
{
data_point() = delete;
data_point(const int& data) :
m_data(data)
{}
int m_data;
};
Run Code Online (Sandbox Code Playgroud)
我也这样声明了这种类型。
typedef std::vector<data_point> data_list;
Run Code Online (Sandbox Code Playgroud)
该结构体的绑定定义如下:
PYBIND11_MODULE(data_lib, ref)
{
py::class_<data_point> dp(ref, "data_point");
dp.def(py::init<const int&>());
dp.def_readwrite("m_data", &data_point::m_data);
}
Run Code Online (Sandbox Code Playgroud)
如何定义 typedef 列表类型的绑定?我不清楚如何在 pybind 文档中执行此操作。
我正在尝试使用 pybind11 将 python 嵌入到我的 C++ 应用程序中。使用以下 CMake 属性,我成功地针对项目的虚拟环境进行编译。
-DPYTHON_EXECUTABLE:FILEPATH=C:/Python/Envs/myproject/Scripts/python.exe
Run Code Online (Sandbox Code Playgroud)
当我运行该应用程序时,出现错误(如下),但没有具体错误。但是我认为它无法加载我正在加载的模块 numpy 。
abort() 已被调用
#include <iostream>
#include <pybind11/embed.h>
namespace py = pybind11;
int main() {
py::scoped_interpreter guard{};
auto sys = py::module::import("sys");
py::print("Hello, World from Python!");
py::print(sys.attr("executable"));
py::print(sys.attr("version"));
// works until here
auto np = py::module::import("numpy");
py::print(np.attr("version"));
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
如果我只导入 sys 模块(位于标准库中),应用程序就可以正常工作。这是崩溃之前应用程序的输出:
Hello, World from Python!
C:\Develop\sandbox\python_binding\cmake-build-debug\bin\python_binding.exe
3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)]
Run Code Online (Sandbox Code Playgroud)
我已将以下目录添加到我的路径中。
PATH=C:\Python\Envs\project\Scripts;C:\Python\Envs\project\Lib
我是否必须指定我正在使用的 python 解释器其他部分的路径,或者这可能是由另一个问题引起的?
我尝试绑定一个静态函数,该函数返回指向另一个类的shared_ptr。
这是示例代码
class Example {
public:
Example() {}
~Example() {}
};
class ABC {
public:
static std::shared_ptr<Example> get_example() {std::make_shared<Example();}
};
void init_abc(py::module & m) {
py::class_<Example>(m, "Example")
.def(py::init<>());
py::class_<ABC>(m, "ABC")
.def_static("get_example", &ABC::get_example);
}
Run Code Online (Sandbox Code Playgroud)
这是Python的一面
example = my_module.ABC.get_example()
Run Code Online (Sandbox Code Playgroud)
然而,python 端抛出了分段错误。
任何想法?
我正在为一个 C++ 类编写 pybindngs,该类将 Google Protobuf 对象作为成员变量。我希望这些绑定函数返回(在 Python 领域)protobuf 对象的 Python 版本(Google 的 proto 编译器本机生成)。
如果我尝试在 pybind 定义中天真地返回 protobuf 的 C++ 版本
.def_readwrite("my_protobuf", &my_protobuf_)
Run Code Online (Sandbox Code Playgroud)
,我收到以下错误:
TypeError: Unable to convert function return value to a Python type! The signature was
(self: MyClass) -> MyProtobufDef
Run Code Online (Sandbox Code Playgroud)
这是有道理的 - 返回类型是 C++ protobuf 对象,而不是 Python protobuf 对象。如何将其转换为 Python 版本的 protobuf?
我有一个混合 C++/Python 项目。它使用pybind11包装 Python 的 C++ 代码,并使用 bazel来构建解决方案。我对这个技术栈非常满意。安装 C++ 编译器、Python 发行版和 bazel 后,bazel run命令即可下载依赖项、构建并运行整个 C++/absl/Python/numpy 集团。
但为了让用户的事情变得更简单,我想将我的代码打包为 PyPI 包,以便可以使用pip install. 我希望该包是跨平台的,可以在 Windows、Linux 和 MacOS 上运行。
在生成新版本时,建立构建、打包并将所有内容上传到 PyPI 的管道的最清晰方法是什么?
我正在为基于 C++ 的加密方案开发一个 python 包装器,其中密钥和密文是非常大的数字(最多 2048 位)。
在 C++ 中,我使用Intel BigNumber 类来存储和处理如此大的数字。
由于 Python 本身支持通过对象“看似”无限位整数,因此我在通过 Python 将此类变量作为参数传递时遇到了麻烦。
py::class_<BigNumber>(m, "BigNumber")
.def(py::init<unsigned int>())
.def(py::init<int>())
.def(py::init<BigNumber>())
.def(py::init([](py::list data) {
size_t length = data.size();
unsigned int* pData = new unsigned int[length];
for (int i = 0; i < length; i++) {
pData[i] = data[i].cast<unsigned int>();
}
return std::unique_ptr<BigNumber>(new BigNumber(pData, length));
}))
.def(py::init([](py::array_t<unsigned int> data) {
py::buffer_info buffer_info = data.request();
unsigned int* pData = static_cast<unsigned int*>(buffer_info.ptr);
std::vector<ssize_t> shape = buffer_info.shape;
return std::unique_ptr<BigNumber>(new BigNumber(pData, …Run Code Online (Sandbox Code Playgroud)