【C++】pybind11:生成 Python 可用的动态库
本文介绍如何使用
pybind11
在 Windows 下编写 C++ 扩展模块并集成到 Python 项目中。全过程涵盖环境准备、CMake 构建、模块开发、导入测试与.pyi
类型存根生成等步骤。推荐使用 PowerShell 终端操作。
一、准备工作
1. 新建项目目录
mkdir example && cd example
2. 创建 Python 虚拟环境(推荐使用 venv)
python -m venv .venv
3. 激活虚拟环境(PowerShell)
.venv\Scripts\activate.ps1
二、确认 Python 编译器信息
使用以下命令查看 Python 版本、使用的编译器和平台:
python -c "import sys; print(sys.version)"
示例输出:
3.12.10 (main, Apr 9 2025, 04:06:22) [MSC v.1943 64 bit (AMD64)]
✅ 请确保后续使用 CMake 编译时所用的编译器与此一致(如 MSVC 64 位)。
三、配置 CMake 构建
1. 创建 CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(example LANGUAGES CXX)# 设置 Python 路径(指向虚拟环境)
set(PYTHON_ROOT "${CMAKE_SOURCE_DIR}/.venv")
set(PYTHON_EXECUTABLE "${PYTHON_ROOT}/Scripts/python.exe")include(FetchContent)# 拉取 pybind11(推荐固定版本)
FetchContent_Declare(pybind11GIT_REPOSITORY https://github.com/pybind/pybind11.gitGIT_TAG v2.11.1
)
FetchContent_MakeAvailable(pybind11)# 编译扩展模块
pybind11_add_module(example example.cpp)
四、编写 C++ 扩展模块
1. 创建 example.cpp
#include <pybind11/pybind11.h>namespace py = pybind11;// 普通函数
int add(int i, int j) {i += j;return i + j;
}// 示例类
class Pet {
public:Pet(const std::string &name) : name(name) {}void setName(const std::string &new_name) { name = new_name; }std::string getName() const { return name; }private:std::string name;
};// 绑定模块
PYBIND11_MODULE(example, m) {m.doc() = "pybind11 example plugin";m.def("add", &add, "A function which adds two numbers");py::class_<Pet>(m, "Pet", "A simple pet class with a name attribute.").def(py::init<const std::string &>(), py::arg("name"), "Constructor that sets the pet's name.").def("set_name", &Pet::setName, py::arg("new_name"), "Set the pet's name.").def("get_name", &Pet::getName, "Get the pet's name.");
}
五、构建模块
1. 编译指令(使用 Visual Studio 2022 x64)
mkdir build && cd build
cmake .. -G "Visual Studio 17 2022" -A x64
cmake --build . --config Release
编译成功后,会在 build/Release/
下生成如下文件:
example.cp312-win_amd64.pyd
六、测试模块导入
进入编译输出目录并尝试导入:
cd Release
python -c "import example"
若无错误提示,说明模块导入成功 ✅
七、生成 .pyi
类型存根(可选但推荐)
1. 安装工具
python -m ensurepip --upgrade
python -m pip install pybind11_stubgen
2. 生成存根文件
python -m pybind11_stubgen example
生成的 example.pyi
存放于 ./stubs/example/
下。
八、打包模块到任意 Python 项目
将以下三项文件复制至目标 Python 项目的 example/
文件夹:
example.cp312-win_amd64.pyd
example.pyi
- 新建
__init__.py
文件:
from .example import *
这样即可正常在其他 Python 项目中使用该模块:
from example import add, Pet