pybind11可以自動幫我們搞定C++和Python型別的串接,讓我們不需要直接處理底層的型別,這對於需要使用C++做部份加速的專案來說,可以讓開發者專住在C++內的開發上。這裡簡單介紹如何使用基本的pybind11的方式。這裡的範例是從官方的https://pybind11.readthedocs.io/en/stable/basics.html 當中改寫以及實驗的結果。
安裝pybind11
pip install pybind11
C++ Part
C++部份這裡展示四個函式,以及使用pybind11提供的micro,最主要的PYBIND11_MODULE,來註冊要提供給Python的函式,須引入<pybind11/pybind11.h>。另外由於要讓pybind11能自動處理C++的STL的型別,這裡還需要引入<pybind11/stl.h>。
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <iostream>
#include <numeric>
#include <vector>
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int sum(std::vector<int> &arr) {
int sum = 0;
return accumulate(arr.begin(), arr.end(), sum);
}
void hello_world(void) {
std::cout << "Hello World!" << std::endl;
return;
}
PYBIND11_MODULE(sum_and_hello, m) {
m.def("add", &add, "add two value function");
m.def("sub", &sub, "sub two value function", pybind11::arg("a"), pybind11::arg("b"));
m.def("sum", &sum, "sum up function");
m.def("hello_world", &hello_world, "hello world function");
}
C++的部份註冊函式的寫法為
PYBIND11_MODULEE(模組名稱, m)
以及
m.def("函式名稱", 函式位址(也就是&函式), "函式介紹");
如果有需要指定參數名稱,可以用
pybind11::arg
CMake Part
編譯C++函式庫的部份使用cmake,主要是用pybind11_add_module: (CMakeLists.txt)
cmake_minimum_required(VERSION 3.18)
set(NAME sum_and_hello)
project(${NAME})
set(CMAKE_CXX_FLAGS "-std=c++11" )
set(CMAKE_BUILD_TYPE "Release")
find_package(PythonLibs 3.9.5 REQUIRED)
find_package(PythonInterp 3.9.5 REQUIRED)
set(pybind11_DIR /media/whuang022/DATA/anaconda3/lib/python3.7/site-packages/pybind11/share/cmake/pybind11)
find_package(pybind11 REQUIRED CONFIG )
pybind11_add_module(module ${NAME}.cpp)
set_target_properties(module PROPERTIES OUTPUT_NAME ${NAME})
set_target_properties(module PROPERTIES SUFFIX ".so")
這裡記得手動引入pybind11_DIR的位置(由於我這邊環境的關係,pybind11裝在python3.7內)
這樣編譯C++的部份,就可以在終端機跑camke和make
mkdir build
cd build
cmake ..
make
完成編譯後得到會得到sum_and_hello.so,並複製到Python專案內即可。
Python Part
這裡模組名稱為sum_and_hello,可以像一般引入模組一樣使用它(run.py):
import sum_and_hello
sum_and_hello.hello_world()
x = sum_and_hello.add(1, 2)
print(x)
y = sum_and_hello.sub(b=1, a=2)
print(y)
z = sum_and_hello.sum([1, 2, 3])
print(x)
這時候在終端機執行
python run.py
可以得到
Hello World!
3
1
3
以上便是用pybind11讓Python呼叫C++的使用方式的簡單介紹。
本文允許重製、散布、傳輸以及修改,但不得為商業目的之使用
使用時必須註明出處自:楊明翰 , 台灣人工智慧與資料科學研究室 https://aistudio.tw