使用Python调用C++库(基于pybind11)

本文将用C++编写一个简单的向量运算库,然后使用pybind11将其封装为python包,再使用python调用。C++程序使用CMake构建。使用C++调用Python模块见:另一篇博客

安装pybind11

使用pybind11可以将使用C++11以上标准编写的函数、类或者lambda表达式封装为python包。

安装pytest

pip3 install pytest

下载pybind11

git clone https://github.com/pybind/pybind11.git

编译安装

cd pybind11
mkdir build
cd build
cmake ..
cmake --build . --config Release --target check
sudo make install

C++

创建cpp文件,命名为example.cpp,在其中实现几个向量运算函数和类,并使用pybind11库将其封装成python包,包名为example,内容如下:

#include <iostream>
#include <vector>

using std::vector;

// 向量内积,返回一个标量,输入的向量要等长
double inner_product(const vector<double>& vec1, const vector<double>& vec2){
    double sum = 0;
    for(int i = 0; i < vec1.size(); i++){
        sum += vec1[i] * vec2[i];
    }
    return sum;
}

// 向量求和,返回一个向量
vector<double> sum(const vector<double>& vec1, const vector<double>& vec2){
    auto result = vec1;
    for(int i = 0; i < vec1.size(); i++){
        result[i] += vec2[i];
    }
    return result;
}

// 定义一个向量类
class Vector{
public:
    Vector()=default;
    ~Vector()=default;

     以下重新实现了上述函数 
    double inner_product(const vector<double>& vec1, const vector<double>& vec2){
        double sum = 0;
        for(int i = 0; i < vec1.size(); i++){
            sum += vec1[i] * vec2[i];
        }
        return sum;
    }

    vector<double> sum(const vector<double>& vec1, const vector<double>& vec2){
        auto result = vec1;
        for(int i = 0; i < vec1.size(); i++){
            result[i] += vec2[i];
        }
        return result;
    }
};

// 使用pybind11将以上函数和类封装为python包
#include <pybind11/pybind11.h>
#include <pybind11/stl.h> // 函数中用到了C++的STL库,所以要包含该头文件
PYBIND11_MODULE(example, m){
    m.doc() = "my example";
    // 封装函数
    m.def("inner_product", &inner_product);
    m.def("sum", &sum);
    
    // 封装用lambda表达式表示的函数
    // 以下函数用于输出指定字符串
    m.def("print", [](std::string& str){
        std::cout << str << std::endl;      
    }); 

    // 封装类
    pybind11::class_<Vector>(m, "Vector")
            .def(pybind11::init())
            .def("inner_product", &Vector::inner_product)
            .def("sum", &Vector::sum);
}

CMakeLists.txt内容如下:

cmake_minimum_required(VERSION 3.0.4)
project(example)

# 添加pybind11依赖
find_package(pybind11 REQUIRED)
message(STATUS "pybind11 version: ${pybind11_VERSION}")

# 添加pybind11头文件路径
include_directories(
  ${pybind11_INCLUDE_DIRS}
)

# 添加python包
pybind11_add_module(example src/example.cpp) 

编译完成后,build文件夹下将会出现example.cpython-3xm-x86_64-linux-gnu.so类似文件,这就是编译生成的库,接下来编写python脚本来调用。

Python

# 添加C++库的路径
import sys
sys.path.append("/home/ubuntu/workspace/example_python_use_cpp/build")

import example
a = [3, 2, 1]
b = [2.1, 5, 2]

# 使用单独的函数
example.print("---- use single function -------")
example.print("a · b = " + str(example.inner_product(a, b)))
example.print("a + b = " + str(example.sum(a, b)))

# 使用类
example.print("---- use class -----------------")
vector = example.Vector() # 类实例化
example.print("a · b = " + str(vector.inner_product(a, b)))
example.print("a + b = " + str(vector.sum(a, b)))

运行结果如下:

---- use single function -------
a · b = 18.3
a + b = [5.1, 7.0, 3.0]
---- use class -----------------
a · b = 18.3
a + b = [5.1, 7.0, 3.0]
  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值