在C++中嵌入并扩展Python,无需用户安装Python2.7
在C++中嵌入Python2.7且无需用户安装Python的解决方案
我来一步步帮你解决这几个嵌入Python时的常见痛点:
1. 无需用户安装Python2.7的实现方式
你可以直接将Python的运行时文件和你的程序打包分发,不需要用户单独安装Python。需要包含的核心文件有:
- 核心动态库:
python27.dll(从Python2.7的安装目录里复制) - Python标准库:复制Python安装目录下的
Lib文件夹,还可以按需裁剪(比如去掉一些不常用的库来减少体积) - 依赖的系统库:比如MSVC的运行时库(如果Python是用MSVC编译的,可能需要
msvcr90.dll之类的,注意要符合微软的分发许可) - 你的自定义Python扩展:放到
Lib/site-packages目录下
把这些文件放在你的程序安装目录的子文件夹里(比如./PythonRuntime),和你的主程序一起打包安装即可。
2. 让python27.dll加载本地目录的Python库而非系统级
Python运行时默认会优先查找系统级的Python安装目录,但你可以通过两种方式修改这个行为:
- 设置PYTHONHOME环境变量:在初始化Python之前(也就是调用
Py_Initialize()之前),在C++代码中设置环境变量,指向你的本地Python运行时目录:
这样Python会把这个目录当作“安装目录”,优先从这里加载标准库。SetEnvironmentVariableA("PYTHONHOME", "./PythonRuntime"); - 修改sys.path:在Python初始化完成后,通过C++代码向
sys.path中插入你的本地目录(放在最前面确保优先级):
这种方式更灵活,还可以按需添加你的扩展所在的路径。PyRun_SimpleString("import sys; sys.path.insert(0, './PythonRuntime/Lib')");
另外要注意,如果你把python27.dll放在程序目录下,系统会优先加载本地的dll,而不是系统里的,所以不需要担心dll版本冲突。
3. 将整个Python系统静态链接到你的DLL
这个方案是可行的,但需要你自己编译Python2.7的静态版本,因为官方默认提供的是动态库。具体步骤大概是:
- 下载Python2.7的完整源码包
- 打开PC目录下的
python.props文件,修改RuntimeLibrary选项为静态编译(比如从MultiThreadedDLL改成MultiThreaded) - 用VS编译整个Python源码,生成静态库
python27.lib - 在你的C++项目中链接这个静态库,同时确保项目的编译选项(比如运行时库)和Python的编译选项一致
这样编译出来的DLL就不再依赖python27.dll了,但缺点也很明显:
- 编译过程比较繁琐,需要处理各种编译选项和依赖
- 生成的DLL体积会大很多(因为包含了整个Python运行时)
- 需要遵守Python的开源许可协议,确保你的分发符合要求
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

