前言

以前更新过一篇pyinstaller—py脚本打包成exe,说的是将Python脚本打包成exe可执行文件,用来在没有安装Python的环境中使用,同时也能一定程度上保护代码不被泄漏。

但在实际开发中,对于多人协作的大型项目,或者是基于支持Python的商业软件的二次开发等,如果将py脚本打包成exe可执行文件,不仅不方便调用,并且运行效率也比较差,此时往往会把py脚本编译成pyd库,再导入调用。

因此,今天就来介绍一下pyd的编译方法以及一些问题。

 

编译pyd前的准备

所谓pyd文件,就是D语言(C/C++综合进化版本)编写的一种dll 文件,相比起容易被反编译的pyc文件,pyd文件目前还没有办法进行反编译,只能被反汇编,因此有很高的安全性,并且运行效率也比较高。

要想编译pyd,首先要通过pip安装Cython和setuptools库。

pip install cython
pip install setuptools

如果Python中连pip也没有,那么可以通过以下方式安装pip。

先将https://bootstrap.pypa.io/get-pip.py下载到本地,然后用Python运行,。

python get-pip.py

装好pip后,setuptools也会自动安装,然后只需要使用pip安装Cython就可以了。

除了Cython和setuptools这两个python库以外,在windows上编译pyd,还需要安装Microsoft Visual C++ 14.0,最简单的方式就是安装Visual Studio 2015以上版本,可以直接去官网下载,或者用我提供的VS2019在线安装程序

在安装时注意勾选上以下几个组件,等待安装完毕即可。

可以看到这种方式只能在线安装,并且会占用较多存储空间,如果不想安装整个Visual Studio开发环境,只想快速部署好pyd的编译所需环境,可以到百度网盘下载安装Microsoft Visual C++ Build Tools离线安装包,将下载下来的ISO镜像装载到虚拟光驱中直接安装即可。

 

pyd的编译

准备好编译环境后就可以进行编译了,首先创建一个用于编译的py脚本例如setup.py,内容如下

import os

import setuptools 
from distutils.core import setup
from Cython.Build import cythonize
from distutils.extension import Extension

extensions = []
if os.path.exists('./test.py'):
    extensions.append(Extension('test',['test.py']))
    
setup(ext_modules = cythonize(extensions, compiler_directives={'language_level': 2}),)

其中的test.py就是要编译的python脚本,而language_level参数为2代表python版本为2.X,如果要打包python3.X版本时,这个参数应该为3。

最后再用python运行这个setup.py并加上两个参数,即可开始编译pyd。

python setup.py build_ext --inplace

对于python2.X版本,编译好的pyd文件名称和py文件相同,例如test.py编译完后为test.pyd;而对于python3.X版本,编译好的pyd文件会带有后缀,例如test.py用64位windows系统上的python3.7编译后是test.cp37-win_amd64.pyd,这个pyd名称不要修改,python在import库时会自动识别。

另外在部署完环境后第一次运行编译时可能会遇到以下的报错。

正在生成
已完成代码的生成
LINK:fata1 error LNK1158:无法运行“rc.exe”
error:command‘C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\x86_amd64\\link.exe’  failed with exit status 1158

这个问题也好解决,将C:\Program Files (x86)\Windows Kits\8.1\bin\x86文件夹中的rc.exercdll.dll拷贝到C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin文件夹中,重新编译即可。

最后,如果打包好的pyd不能正常import使用,可以查看报错中提示缺失的模块,如果依然查不到,可以试试Depends软件查看缺失的dll。

 


孤独和寂寞不一样,
寂寞会发慌,
孤独则是饱满的。

——蒋勋