[TOC]
0 准备 项目文件夹结构树如下:
1 2 3 4 5 6 7 pybind11_setup_demo └─demo │ setup.py │ test.py │ └─src example.cpp
example.cpp
1 2 3 4 5 6 7 8 9 10 11 #include <pybind11/pybind11.h> namespace py = pybind11;int square (int x) { return x * x; }PYBIND11_MODULE (example, m) { m.def ("square" , &square); }
test.py
1 2 3 4 5 6 7 import examplehelp (example) result = example.square(5 )print (result)
参考文章:pybind11—python C/C++扩展编译 - 简书 (jianshu.com)
setup.py
1 2 3 4 5 6 7 8 9 10 11 12 from setuptools import setupfrom setuptools import Extension example_module = Extension(name = 'example' , sources = ['src/example.cpp' ], include_dirs = [r'D:\anaconda3\envs\pybind11\include' , r'D:\anaconda3\envs\pybind11\Lib\site-packages\pybind11\include' ] ) setup(ext_modules = [example_module])
打开终端,进入到setup.py
文件所在目录,运行下面命令:
1 python setup.py build_ext --inplace
1 2 3 4 5 6 7 8 9 10 11 running build_ext building 'example' extension creating build creating build\temp.win-amd64-cpython-38 creating build\temp.win-amd64-cpython-38\Release creating build\temp.win-amd64-cpython-38\Release\src ... 正在创建库 build\temp.win-amd64-cpython-38\Release\src\example.cp38-win_amd64.lib 和对象 build\temp.win-amd64-cpython-38\Release\src\example.cp38-win_amd64.exp 正在生成代码 已完成代码的生成 copying build\lib.win-amd64-cpython-38\example.cp38-win_amd64.pyd ->
测试拓展模块:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Help on module example: NAME example FUNCTIONS square(...) method of builtins.PyCapsule instance square(arg0: int) -> int FILE d:\pybind11_setup_demo\demo\example.cp38-win_amd64.pyd 25
2. pybind11.setup_helpers 参考文档网址:Build systems - pybind11 documentation
这种方法和上一种方法的区别在于,后者需要安装在Python环境中pip install pybind11
。pybind11提供了setup_helpers
用于简化setuptools的构建过程(作用有点类似于pybind11提供的CMake函数pybind11_add_module
)。
setup.py
1 2 3 4 5 6 7 8 9 10 11 from setuptools import setupfrom pybind11.setup_helpers import Pybind11Extension, build_ext ext_modules = [ Pybind11Extension( "example" , ["src/example.cpp" ], ), ] setup(cmdclass = {"build_ext" : build_ext}, ext_modules = ext_modules)
同样,打开终端,进入到setup.py
文件所在目录,运行下面命令:
1 python setup.py build_ext --inplace
1 2 3 4 5 6 7 8 9 10 11 running build_ext building 'example' extension creating build creating build\temp.win-amd64-cpython-38 creating build\temp.win-amd64-cpython-38\Release creating build\temp.win-amd64-cpython-38\Release\src ... 正在创建库 build\temp.win-amd64-cpython-38\Release\src\example.cp38-win_amd64.lib 和对象 build\temp.win-amd64-cpython-38\Release\src\example.cp38-win_amd64.exp 正在生成代码 已完成代码的生成 copying build\lib.win-amd64-cpython-38\example.cp38-win_amd64.pyd ->
测试拓展模块:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Help on module example: NAME example FUNCTIONS square(...) method of builtins.PyCapsule instance square(arg0: int) -> int FILE d:\pybind11_setup_demo\demo\example.cp38-win_amd64.pyd 25
效果和第一种没有差别,但在setup.py
文件的编写上更加方便。
3. cppimport 参考网址:tbenthompson/cppimport: Import C++ files directly from Python! (github.com)
这种方法更加简单,甚至不需要编写setup.py
文件。只需在Python环境中安装cppimport
库即可。
修改example.cpp
如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <pybind11/pybind11.h> namespace py = pybind11;int square (int x) { return x * x; }PYBIND11_MODULE (example, m) { m.def ("square" , &square); }
打开终端,进入到example.cpp
文件所在的src
目录下,打开python解释器运行下面代码:
1 2 3 import cppimport.import_hookimport example example.square(5 )
运行结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 PS D:\pybind11_setup_demo\demo\src> python Python 3.8.12 (default, Oct 12 2021, 03:01:40) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32 Type "help" , "copyright" , "credits" or "license" for more information. >>> import cppimport.import_hook >>> import example cl: 命令行 warning D9002 :忽略未知选项“-std=c++11” cl: 命令行 warning D9002 :忽略未知选项“-fvisibility=hidden” .rendered.example.cpp 正在创建库 ...\pybind11_setup_demo\demo\src\example.cp38-win_amd64.lib 和对象 ...\pybind11_setup_demo\demo\src\example.cp38-win_amd64.exp 正在生成代码 已完成代码的生成 >>> example.square(5) 25
运行成功后,在同目录下会自动生成一个pyd文件。
总结