Windows下编译pybind11头文件报错求助
MINGW64下pybind11编译错误及跨平台适配解决方案
问题概述
用pybind11实现C++与Python交互,Linux环境编译成功,但在Windows10 64位MINGW64环境编译时,pybind11头文件出现编译错误,需获取问题解决思路、pybind11替代方案或Linux到Windows的跨编译详细指南。
代码片段
pyBind.cpp
#include "pybind11/pybind11.h" #include "pythonFunctionBind.hpp" namespace py = pybind11; PYBIND11_MODULE(pybindTest,m) { m.doc() = "pybind test but i don't know where to put my project"; m.def("A",&returnAP,"return 3"); m.def("B",&returnBP,"return 4"); }
pythonFunctionBind.hpp
#ifndef pythonBind_hpp #define pythonBind_hpp #include <vector> #include <iostream> class A { public: int i; int j; void write(); void print(); int returnP(); std::vector<int> s; protected: int p; void writeI(); void writeJ(); virtual void writeP(); }; class B: public A { protected: void writeP() override; }; int returnAP(); int returnBP(); #endif
pythonFunctionBind.cpp
#include "pythonFunctionBind.hpp" void A::write() { writeI(); writeJ(); writeP(); } void A::print() { std::cout << i << j << p << "\n"; } int A::returnP() { return p; } void A::writeI() { i = 1; } void A::writeJ() { j = 2; } void A::writeP() { p = 3; } void B::writeP() { p = 4; } int returnAP() { A a; a.write(); int p = a.returnP(); return p; } int returnBP() { B b; b.write(); int p = b.returnP(); return p; }
编译命令
g++ -std=c++14 -fpermissive -shared -fPIC -static-libgcc -static-libstdc++ -I./include/ -I./pybind11/include/ `python -m pybind11 --includes` pyBind.cpp pythonFunctionBind.cpp -o pybindTest.pyd `python-config --ldflags` -lmingw32 -mwindows -L libwinpthread-1.dll
错误信息
In file included from pybind11/detail/../detail/Python.h:63, from pybind11/detail/../detail/common.h:266, from pybind11/detail/../attr.h:13, from pybind11/detail/class.h:12, from pybind11/pybind11.h:13, from pyBind.cpp:2: pybind11/detail/../detail/cpython/fileutils.h:17:12: warning: declaration does not declare anything [-f permissive] 17 | PyAPI_FUNC(_Py_error_handler); _Py_GetErrorHandler(const char *errors); | ^~~~~~~~~~~~~~~~~ pybind11/detail/../detail/pyport.h:683:77: note: in definition of macro 'PyAPI_FUNC' 683 | # define PyAPI_FUNC(RTYPE) Py_IMPORTED_SYMBOL RTYPE | ^~~~~ In file included from pybind11/detail/../detail/fileutils.h:23, from pybind11/detail/../detail/Python.h:159: pybind11/detail/../detail/cpython/fileutils.h:17:71: error: expected constructor, destructor, or type c onversion before ';' token 17 | PyAPI_FUNC(_Py_error_handler); _Py_GetErrorHandler(const char *errors); |
解决思路
1. 排查Python环境兼容性
- 官方Windows Python是MSVC编译的,与MINGW的ABI不兼容,会导致头文件解析错误。必须使用MINGW编译的Python,比如通过MSYS2仓库安装
mingw-w64-x86_64-python。 - 验证Python架构:确保Python是64位版本,与MINGW64工具链匹配。
2. 修正编译命令
- 移除
-fPIC:Windows下MINGW编译共享库不需要该参数(仅Linux需要)。 - 替换
python-config --ldflags为python -m pybind11 --ldflags:避免MINGW下python-config输出MSVC相关冲突参数。 - 删除
-lmingw32 -mwindows:这是编译GUI程序的选项,Python扩展无需依赖。 - 调整后示例命令:
g++ -std=c++14 -fpermissive -shared -static-libgcc -static-libstdc++ -I./include/ -I./pybind11/include/ `python -m pybind11 --includes` pyBind.cpp pythonFunctionBind.cpp -o pybindTest.pyd `python -m pybind11 --ldflags`
3. 临时头文件修复(不推荐长期使用)
错误源于_Py_error_handler类型未定义,可在包含pybind11头文件前手动声明:
typedef int (*_Py_error_handler)(void); #include "pybind11/pybind11.h"
但更根本的是解决Python环境兼容性问题,修改pybind11源码可能导致后续版本兼容问题。
pybind11替代方案
- Boost.Python:老牌绑定库,兼容性强,支持多平台,但依赖Boost库,编译体积较大。
- Cython:通过类Python语法生成C扩展,适合Python开发者,无需深入C++,跨平台编译更简单。
- SWIG:多语言绑定工具,基于配置文件,适合已有大量C++代码快速绑定场景。
Linux到Windows跨编译指南(MINGW64)
步骤1:安装交叉编译工具链
在Linux上安装MINGW64工具链:
sudo apt install mingw-w64
步骤2:准备MINGW版本Python
- 从MSYS2仓库下载预编译的MINGW64 Python,解压到指定路径(如
/opt/mingw-python),包含头文件和库文件。
步骤3:用CMake管理编译(推荐)
创建CMakeLists.txt:
cmake_minimum_required(VERSION 3.15) project(pybindTest) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) set(Python_ROOT_DIR /opt/mingw-python) find_package(Python REQUIRED COMPONENTS Development) add_subdirectory(pybind11) pybind11_add_module(pybindTest pyBind.cpp pythonFunctionBind.cpp) target_include_directories(pybindTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
步骤4:执行编译
mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make
生成的.pyd文件即可在Windows10 64位环境使用。
内容的提问来源于stack exchange,提问作者Michael Gunnarson
相关产品推荐
相关产品推荐

