工具集
pybind11原理分析,使用案例
104_Pybind11
2. 基本使用
2.1. 安装pybind11
一、pybind11是什么?
pybind11是一个只有头文件的轻量级库,它在导出C++类型到Python的同时,也导出Python类型到C++中,其主要目的是建立现有C++代码的Python绑定。它与David Abrahams的Boost.Python库目的和语法相似,都是通过编译期内省来推断类型信息,以最大程度地降低传统扩展模块中的重复样板代码。
二、如何安装
三、pybind11的头文件路径的查询方法如下:
Bash parallels@ubuntu-linux-20-04-desktop:/$ python3 -m pybind11 --includes
-I/usr/local/include/python3.8 -I/home/parallels/.local/lib/python3.8/site-packages/pybind11/include
四、pybind11头文件中的内容:
Bash parallels@ubuntu-linux-20-04-desktop:/$ tree /home/parallels/.local/lib/python3.8/site-packages/pybind11/include
/home/parallels/.local/lib/python3.8/site-packages/pybind11/include
└── pybind11
├── attr.h
├── buffer_info.h
├── cast.h
├── chrono.h
├── common.h
├── complex.h
├── detail
│ ├── class.h
│ ├── common.h
│ ├── descr.h
│ ├── init.h
│ ├── internals.h
│ ├── type_caster_base.h
│ └── typeid.h
├── eigen
│ ├── common.h
│ ├── matrix.h
│ └── tensor.h
├── eigen.h
├── embed.h
├── eval.h
├── functional.h
├── gil.h
├── iostream.h
├── numpy.h
├── operators.h
├── options.h
├── pybind11.h
├── pytypes.h
├── stl
│ └── filesystem.h
├── stl_bind.h
├── stl.h
└── type_caster_pyobject_ptr.h
4 directories, 31 files
2.2. Python使用C++
一、编写绑定代码:example.cpp
C++ #include <pybind11/pybind11.h>
int add ( int i , int j ) {
return i + j ;
}
PYBIND11_MODULE ( example , m ) {
m . def ( "add" , & add , "A function which adds two numbers" );
}
二、通过g++编译生成so
上面的源码使用到了头文件#include <pybind11/pybind11.h>
,所以下面编译时需要指pybind11头文件所在的目录
Bash # python3 -m pybind11 --includes即是获取pybind11头文件的绝对路径
g++ -O3 -Wall -shared -std= c++11 -fPIC $( python3 -m pybind11 --includes) example.cpp -o example$( python3-config --extension-suffix)
三、也可以通过python生成so,本质跟上述g++一样
编写编译脚本:
Python from setuptools import setup , Extension
# pip install pybind11
# pybind11包中有include目录,用于编译出so
functions_module = Extension (
name = 'example' ,
sources = [ 'example.cpp' ],
extra_compile_args = [ "-O3" , "-fPIC" ],
include_dirs = [ '/home/parallels/.local/lib/python3.8/site-packages/pybind11/include' ],
)
# 效果等同于:g++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)
setup ( ext_modules = [ functions_module ])
# python setup.py build 可以看到产生了build文件夹,并且里面有生成的so动态库,用于python import使用c++
使用python执行编译:
Bash # 可以看到产生了build文件夹,并且里面有生成的so动态库,用于python import使用c++
python setup.py build
# 查看build目录
parallels@ubuntu-linux-20-04-desktop:~/blogs/code/1_pybind11$ tree build/
build/
├── lib.linux-aarch64-3.8
│ └── example.cpython-38-aarch64-linux-gnu.so
└── temp.linux-aarch64-3.8
└── example.o
2 directories, 2 files
四、运行查看结果
运行脚本:
Python # 导入so文件
import example
# 输出模块的文件地址
module_path = example . __file__
print ( f "模块路径: { module_path } " )
rst = example . add ( 1 , 2 )
print ( f "运行结果: { rst } " )
运行结果:
Bash parallels@ubuntu-linux-20-04-desktop:~/blogs/code/1_pybind11$ python test_example.py
模块路径:/home/parallels/blogs/code/1_pybind11/example.cpython-38-aarch64-linux-gnu.so
运行结果:3
2.3. C++使用Python
一、编写调用程序test_example.cpp
C++ #include <pybind11/embed.h>
#include <iostream>
namespace py = pybind11 ;
int main () {
// start the interpreter and keep it alive
py :: scoped_interpreter guard {};
py :: module t = py :: module :: import ( "example" );
py :: object result = t . attr ( "add" )( 1 , 2 );
std :: cout << "Result is: " << result . cast < int > () << std :: endl ;
return 0 ;
}
二、编译libpython3.8.so
Bash cd /home/parallels/software
wget -c https://www.python.org/ftp/python/3.8.10/Python-3.8.10.tgz
tar -zxvf Python-3.8.10.tgz
# 制作python共享库,需要加上--enable-shared
./configure --enable-shared
sudo make
sudo make install
# 查看libpython3.8.so的路径
parallels@ubuntu-linux-20-04-desktop:~/software$ ls -lt /usr/local/lib/
total 40580
drwxr-xr-x 2 root root 4096 Oct 2 16 :01 pkgconfig
drwxrwsr-x 36 root staff 4096 Oct 2 16 :01 python3.8
lrwxrwxrwx 1 root root 19 Oct 2 16 :01 libpython3.8.so -> libpython3.8.so.1.0
-rwxr-xr-x 1 root root 19907680 Oct 2 16 :01 libpython3.8.so.1.0
-rwxr-xr-x 1 root root 8032 Oct 2 16 :01 libpython3.so
drwxr-xr-x 36 root root 12288 Oct 2 15 :59 python3.9
lrwxrwxrwx 1 root root 19 Oct 2 15 :59 libpython3.9.so -> libpython3.9.so.1.0
-rwxr-xr-x 1 root root 21608808 Oct 2 15 :59 libpython3.9.so.1.0
drwxrwsr-x 4 root staff 4096 Oct 1 19 :04 python2.7
三、编译出可执行文件
Bash g++ -std= c++11 $( python3 -m pybind11 --includes) test_example.cpp -Wl,-rpath,$( python3-config --prefix) /lib $( python3-config --prefix) /lib/libpython3.8.so -o test_example && ./test_example
# 输出结果:
Result is: 3
3. 参考
https://www.hbblog.cn/python%26C%2B%2B/python%E5%92%8CC%E7%9A%84%E4%BA%A4%E4%BA%92/#251
GitHub - pybind/pybind11: Seamless operability between C++11 and Python
00.%E4%BB%8B%E7%BB%8D.md
最后更新:
2024-04-14