c++导出so给python调用的两种方法

1.1 使用pybind11

示例代码

PyBind11 是一个轻量级的头文件库,它使得将 C++ 和 Python 代码集成变得非常简单。PyBind11 支持现代 C++ 特性,并且可以很容易地将 C++ 函数、类和数据结构暴露给 Python。

主要步骤:
安装 PyBind11:可以通过 pip 或者包管理器安装。
编写绑定代码:创建一个包含 PYBIND11_MODULE 的 C++ 文件来定义模块接口。
编译为共享库:使用 CMake 或其他构建工具编译代码为 .so 文件。
Python 导入:在 Python 中直接导入生成的模块。

注意!!!:
PYBIND11_MODULE定义的名称要和你的so名称一模一样, 不然可能会出现

Traceback (most recent call last):
  File "test.py", line 1, in <module>
    import libexample_pybind11
ImportError: dynamic module does not define module export function (PyInit_libexample_pybind11)
#include <pybind11/pybind11.h>

namespace py = pybind11;

int add(int i, int j) {
    return i + j;
}

PYBIND11_MODULE(example, m) {
    m.doc() = "pybind11 example plugin"; // optional module docstring
    m.def("add", &add, "A function which adds two numbers");
}

1.2 使用 SWIG (Simplified Wrapper and Interface Generator)

SWIG 是一种强大的工具,用于生成 C/C++ 代码与多种编程语言之间的接口,包括 Python。它支持复杂的 C++ 功能,如模板、命名空间等,并且允许你自定义包装代码。

主要步骤:
编写接口文件:创建一个 .i 文件描述如何包装 C++ 代码。
运行 SWIG:使用 SWIG 命令行工具生成包装代码。
编译包装代码:编译生成的代码以及原始 C++ 源码为共享库。
Python 导入:在 Python 中导入生成的模块。

// MyClass.cpp:
class MyClass {
public:
    MyClass();
    ~MyClass();
    void greet(const char* name);
};

// myclass.i
%module myclass
%{
#include "myclass.h"
%}

%include "myclass.h"

总结
PyBind11:推荐用于现代 C++ 项目,易于使用且文档丰富。
SWIG:适用于大型项目或者需要高度定制化的场景。

2.1 关于pybind11的路径问题的几种解决方案

出现如下报错, 原因是找不到pybind11的安装路径, 其原因大概率是因为python多版本安装的问题, 有几种解决方案

-- Found Python3: /usr/bin/python3.6 (found version "3.6.8") found components: Interpreter Development 
CMake Error at CMakeLists.txt:22 (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 find one.

  Could not find a package configuration file provided by "pybind11" with any
  of the following names:

    pybind11Config.cmake
    pybind11-config.cmake

  Add the installation prefix of "pybind11" to CMAKE_PREFIX_PATH or set
  "pybind11_DIR" to a directory containing one of the above files.  If
  "pybind11" provides a separate development package or SDK, be sure it has
  been installed.

2.1.1 方案一: 使用 FetchContent 下载并包含 PyBind11

include(FetchContent)
FetchContent_Declare(
  pybind11
  GIT_REPOSITORY https://gitee.com/yunfeiliu/pybind11.git # 这里可以使用https://github.com/pybind/pybind11.git, 根据自己的网络决定
#   GIT_TAG        v2.10.4  # 选择一个稳定的版本标签
)
FetchContent_MakeAvailable(pybind11)

2.1.2 方案二: 直接指定pybind11的路径

# 先从Cmake的输出看你使用的python版本, 比如我这里使用的是python3.6
# 然后执行python3.6 -m pip show pybind11, 查看Location字段的值, 填到下面
set(CMAKE_PREFIX_PATH "/usr/local/lib/python3.6/site-packages")
find_package(pybind11 REQUIRED)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值