# python-cpp **Repository Path**: MushroomHead/python-cpp ## Basic Information - **Project Name**: python-cpp - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-06-26 - **Last Updated**: 2025-06-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # C++ Python 相互调用演示项目 [![MSYS2 UCRT64](https://img.shields.io/badge/MSYS2-UCRT64-blue.svg)](https://www.msys2.org/) [![CMake](https://img.shields.io/badge/CMake-3.12+-green.svg)](https://cmake.org/) [![Python](https://img.shields.io/badge/Python-3.7+-yellow.svg)](https://www.python.org/) [![pybind11](https://img.shields.io/badge/pybind11-2.10+-red.svg)](https://pybind11.readthedocs.io/) 这个项目演示了如何在Windows环境下使用MSYS2 UCRT64实现C++和Python之间的高效双向调用,包括: 1. **Python调用C++接口** - 主程序是Python,调用C++提供的高性能计算功能 2. **Python向C++注册回调** - C++在执行过程中可以回调Python函数进行结果处理 3. **异步回调支持** - C++后台线程可以安全地调用Python回调函数 4. **完整的类型转换** - 支持基础类型和复杂数据结构的双向传递 ## 🌟 主要特性 - ✅ **双向调用** - Python ↔ C++ 完整互操作 - ✅ **类型安全** - pybind11确保类型转换安全 - ✅ **异步支持** - 多线程环境下的安全回调 - ✅ **高性能** - 充分发挥C++性能优势 - ✅ **易于使用** - 一键构建和运行脚本 - ✅ **完整文档** - 详细的安装和使用说明 ## 项目结构 ``` cpp-python/ ├── src/ │ ├── calculator.h # C++头文件定义 │ ├── calculator.cpp # C++核心实现 │ └── bindings.cpp # pybind11绑定代码 ├── main.py # Python主程序 ├── build_and_run.sh # 一键构建运行脚本 ├── CMakeLists.txt # CMake构建配置 ├── requirements.txt # Python依赖 └── README.md # 本文件 ``` ## 功能特性 ### C++接口(供Python调用) - `add(a, b)` - 两数相加 - `multiply(a, b)` - 两数相乘 - `divide(a, b)` - 两数相除 - `complex_calculation(x, y, z)` - 复杂计算,会调用Python回调 ### Python回调接口(供C++调用) - `log_callback(message)` - 日志回调,C++日志通过此函数输出 - `result_callback(step1, step2)` - 结果处理回调,C++将中间结果传给Python处理 ## 环境要求 ### 基础环境 - Windows 10/11 - MSYS2 UCRT64环境 - Python 3.7+ - CMake 3.12+ - GCC编译器 - Ninja构建工具 - pybind11库 ### 详细安装步骤 #### 1. 安装MSYS2 1. 从 [MSYS2官网](https://www.msys2.org/) 下载并安装MSYS2 2. 安装完成后,打开 **MSYS2 UCRT64** 终端(重要:必须是UCRT64版本) #### 2. 更新系统包 ```bash pacman -Syu # 如果提示重启终端,请关闭后重新打开MSYS2 UCRT64终端 pacman -Su ``` #### 3. 安装开发工具链 ```bash # 安装基础编译工具 pacman -S mingw-w64-ucrt-x86_64-gcc pacman -S mingw-w64-ucrt-x86_64-cmake pacman -S mingw-w64-ucrt-x86_64-ninja # 安装Python和相关工具 pacman -S mingw-w64-ucrt-x86_64-python pacman -S mingw-w64-ucrt-x86_64-python-pip # 安装pybind11 pacman -S mingw-w64-ucrt-x86_64-pybind11 ``` #### 4. 验证安装 ```bash # 检查工具版本 gcc --version cmake --version ninja --version python --version pip --version ``` #### 5. 可选:设置环境变量 将MSYS2的bin目录添加到Windows的PATH环境变量中: ``` D:\program\msys64\ucrt64\bin ``` (路径根据你的MSYS2安装位置调整) ### 一键安装脚本 [install_deps.sh](install_deps.sh) 在MSYS2 UCRT64终端中运行: ```bash chmod +x install_deps.sh ./install_deps.sh ``` ## 项目获取和准备 ### 克隆项目 ```bash # 克隆项目到本地 git clone <项目地址> cd cpp-python # 或者直接下载项目压缩包并解压 ``` ### 进入MSYS2 UCRT64环境 确保在 **MSYS2 UCRT64** 终端中执行所有命令: ```bash # 进入项目目录 cd /d/path/to/cpp-python # 根据实际路径调整 ``` ### Python环境隔离(可选但推荐) 为了避免污染系统Python环境,强烈建议使用虚拟环境: ```bash # 设置虚拟环境(首次使用) ./setup_venv.sh # 或者手动创建虚拟环境 python -m venv cpp_python_venv source cpp_python_venv/bin/activate pip install -r requirements.txt deactivate ``` ## 快速开始 ### 方法1:一键构建运行(推荐) #### 使用系统Python环境 ```bash ./build_and_run.sh ``` #### 使用虚拟环境(推荐) ```bash # 首次设置虚拟环境 ./setup_venv.sh # 使用虚拟环境构建和运行 ./build_and_run.sh --use-venv ``` ### 方法2:手动构建 ```bash # 1. 安装Python依赖 pip install -r requirements.txt # 2. 创建构建目录 mkdir .build cd .build # 3. CMake配置 cmake .. # 4. 编译 cmake --build . --config Release # 5. 运行演示 cd .. python main.py ``` ## 演示内容 程序会依次演示: 1. **基本调用** - Python调用C++的计算函数 2. **回调注册** - Python注册日志回调函数给C++ 3. **复杂交互** - C++执行计算过程中回调Python处理中间结果 4. **异步回调** - C++异步任务通过回调通知Python ## 核心技术 ### pybind11绑定 使用pybind11将C++类和函数暴露给Python: ```cpp py::class_(m, "Calculator") .def(py::init<>()) .def("add", &Calculator::add) .def("set_log_callback", &Calculator::setLogCallback); ``` ### 回调函数支持 C++使用std::function存储Python回调: ```cpp using PyCallback = std::function; PyCallback logCallback_; ``` Python注册回调: ```python calc.set_log_callback(handler.log_callback) ``` ### 线程安全 项目支持异步调用,C++可以在后台线程中调用Python回调函数。 ## 预期输出 运行程序后,你会看到类似以下的输出: ``` C++ Python 相互调用演示程序 模块版本: 1.0.0 === 1. 基本的Python调用C++接口 === [C++] Calculator initialized [C++] Performing addition: 10 + 5 = 15 Python调用: add(10, 5) = 15 === 2. Python向C++注册回调函数 === 已注册日志回调函数 [Python Log #1] [C++] Log callback registered [Python Log #2] [C++] Performing addition: 20 + 30 = 50 === 3. 复杂的双向交互 === [Python Callback] 收到C++传来的中间结果: step1=15, step2=45 [Python Callback] Python处理后的结果: 52 最终结果: 52 === 演示完成 === ✓ Python成功调用了C++接口 ✓ Python成功向C++注册了回调函数 ✓ C++成功回调了Python函数 ✓ 实现了双向的复杂交互 ``` ## 扩展建议 1. **错误处理** - 添加更完善的异常处理机制 2. **类型支持** - 支持更多C++和Python类型的转换 3. **性能优化** - 对于大数据传输场景进行优化 4. **多线程** - 更复杂的多线程回调场景 ## 常见问题和故障排除 ### 环境问题 **Q: 必须使用MSYS2 UCRT64吗?** A: 是的,本项目专门为MSYS2 UCRT64环境优化。其他环境(如MINGW64、CLANG64)可能出现兼容性问题。 **Q: 为什么要用UCRT64而不是MINGW64?** A: UCRT64使用Universal C Runtime,与现代Windows和Python版本兼容性更好,避免了很多运行时库冲突问题。 **Q: 安装包时提示"externally-managed-environment"?** A: 这是正常的,MSYS2的Python是系统管理的。错误信息中已经显示依赖已满足,可以忽略警告继续构建。 **Q: 我已经用pacman安装了pybind11,还需要requirements.txt吗?** A: 取决于使用场景: - **系统环境**:不需要,构建脚本会自动检测已安装的pybind11 - **虚拟环境**:需要,因为虚拟环境无法访问pacman安装的包 - **最小化安装**:可以使用 `requirements-minimal.txt`(空文件) ### 编译问题 **Q: 编译时找不到Python头文件?** A: 确保已安装 `mingw-w64-ucrt-x86_64-python` 包,它包含了Python开发头文件。 **Q: CMake找到错误的Python版本?** A: Shell脚本已经处理了这个问题,它会强制CMake使用检测到的Python版本。如果仍有问题,检查PATH环境变量。 **Q: 链接时出现undefined symbols错误?** A: 确保所有依赖包都是UCRT64版本,不要混用MINGW64和UCRT64的包。 ### 运行问题 **Q: 运行时找不到模块?** A: 确保编译成功,并且Python能找到.build目录中的.pyd文件。检查文件名,应该类似 `cpp_python_demo.cp312-win_amd64.pyd`。 **Q: 运行时提示DLL加载失败?** A: 这通常是运行时库不匹配导致的。确保: - 使用MSYS2 UCRT64终端运行程序 - 所有依赖都是UCRT64版本 - Python版本与编译时使用的版本一致 **Q: 回调函数不工作?** A: 确保Python对象的生命周期,避免回调函数被过早释放。在复杂场景中,可以使用全局变量保持回调对象引用。 ### 性能问题 **Q: 编译速度很慢?** A: 确保已安装Ninja构建工具,它比Make快很多: ```bash pacman -S mingw-w64-ucrt-x86_64-ninja ``` **Q: 首次运行pybind11下载很慢?** A: 可能是网络问题。可以考虑配置代理或使用国内镜像。 ### 其他问题 **Q: Shell脚本权限不足?** A: 在MSYS2中给脚本添加执行权限: ```bash chmod +x build_and_run.sh ``` **Q: 想要在Windows CMD中直接运行?** A: 不推荐。本项目依赖MSYS2环境,建议始终在MSYS2 UCRT64终端中操作。 **Q: 如何清理构建文件?** A: 删除.build目录即可: ```bash rm -rf .build ``` ### 虚拟环境问题 **Q: 为什么建议使用虚拟环境?** A: 虚拟环境可以: - 隔离项目依赖,避免版本冲突 - 保持系统Python环境清洁 - 便于项目迁移和部署 - 更好地管理不同项目的依赖 **Q: 虚拟环境和系统环境有什么区别?** A: - 系统环境:使用MSYS2安装的Python,依赖全局安装 - 虚拟环境:项目独立的Python环境,依赖隔离安装 **Q: 如何在不同的虚拟环境之间切换?** A: ```bash # 退出当前虚拟环境 deactivate # 激活另一个虚拟环境 source another_venv/bin/activate ``` **Q: 虚拟环境占用太多磁盘空间?** A: 可以删除不需要的虚拟环境: ```bash rm -rf cpp_python_venv ``` **Q: 构建脚本如何检测虚拟环境?** A: 脚本检查 `cpp_python_venv` 目录是否存在,以及是否激活了虚拟环境(通过 `$VIRTUAL_ENV` 环境变量)。 ## 📋 完整使用流程总结 ### 首次使用(完整流程) 1. **安装MSYS2** ```bash # 从 https://www.msys2.org/ 下载并安装MSYS2 ``` 2. **配置开发环境** ```bash # 打开MSYS2 UCRT64终端 # 运行一键安装脚本 ./install_deps.sh ``` 3. **获取项目代码** ```bash # 克隆或下载项目 git clone <项目地址> cd cpp-python ``` 4. **构建和运行** ```bash # 方法1:使用系统Python环境 ./build_and_run.sh # 方法2:使用虚拟环境(推荐) ./setup_venv.sh # 首次设置虚拟环境 ./build_and_run.sh --use-venv # 使用虚拟环境构建运行 ``` ### 日常开发流程 #### 使用系统Python环境 ```bash # 1. 进入MSYS2 UCRT64终端 cd /d/path/to/cpp-python # 2. 修改代码后重新构建 ./build_and_run.sh # 3. 或者手动步骤 rm -rf .build # 清理旧构建 mkdir .build && cd .build # 创建构建目录 cmake .. # CMake配置 cmake --build . --config Release # 编译 cd .. && python main.py # 运行 ``` #### 使用虚拟环境(推荐) ```bash # 1. 进入MSYS2 UCRT64终端 cd /d/path/to/cpp-python # 2. 使用虚拟环境构建 ./build_and_run.sh --use-venv # 3. 或者手动激活虚拟环境 source cpp_python_venv/bin/activate # 激活虚拟环境 ./build_and_run.sh # 构建运行 deactivate # 退出虚拟环境 # 4. 或者完全手动步骤 source cpp_python_venv/bin/activate rm -rf .build && mkdir .build && cd .build cmake -DPYTHON_EXECUTABLE="$(which python)" .. cmake --build . --config Release cd .. && python main.py deactivate ``` ### 项目文件说明 | 文件/目录 | 说明 | |----------|------| | `src/calculator.h` | C++接口定义 | | `src/calculator.cpp` | C++核心实现 | | `src/bindings.cpp` | pybind11绑定代码 | | `main.py` | Python主程序 | | `build_and_run.sh` | 一键构建运行脚本 | | `install_deps.sh` | 一键环境安装脚本 | | `setup_venv.sh` | Python虚拟环境设置脚本 | | `CMakeLists.txt` | CMake构建配置 | | `requirements.txt` | Python依赖列表(含pybind11) | | `requirements-minimal.txt` | 最小依赖列表(pacman用户可选) | | `.build/` | 构建目录(自动生成) | | `cpp_python_venv/` | Python虚拟环境目录(可选生成) | ## 🤝 贡献指南 欢迎提交Issue和Pull Request来改进这个项目! 1. Fork本项目 2. 创建特性分支 (`git checkout -b feature/amazing-feature`) 3. 提交更改 (`git commit -m 'Add some amazing feature'`) 4. 推送到分支 (`git push origin feature/amazing-feature`) 5. 打开Pull Request ## 📄 许可证 本项目采用MIT许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。 ## 🙏 致谢 - [pybind11](https://github.com/pybind/pybind11) - 优秀的C++/Python绑定库 - [MSYS2](https://www.msys2.org/) - Windows下的Unix开发环境 - [CMake](https://cmake.org/) - 跨平台构建系统 --- **如果这个项目对你有帮助,请给个⭐星标支持!**