Programming Recipes
Recipes是从一本书上看来的,即有诀窍又有食谱的意思。这里想记一些工作中遇到的问题和解决方法,说决窍有点过了,说食谱照单做又不足,所以Recipe这个词两个意思都有混合起来正合适。
1、Windows上的PyInstaller,在bootloader开始运行时会调用SetDllDirectory() Win32 API来限定Dll的搜索目录。如果你打包程序里面会调用或依赖外部DLL这将报WinError 126错误,所以需要在bootloader运行之后、你的外部DLL加载之前取消这个限制。至于如何取消请参考MSDN,bootloader对SetDllDirectory()的调用请参考PyInstaller bootloader代码。
2、已有Python实现库,如何做成万金油C接口、放在DLL里面给其它语言调用?有一种对自己看起来颇折腾实则省缺了重复实现、用户又感觉不到的办法:把你自己的Python库和绿色版的Python解释器当作DLL资源嵌进去。在DLL_PROCESS_ATTACH时释放解释器和自己的库到临时目录,DLL_PROCESS_DETACH时清理,在接品实现中用Python C API调自己的库。其实这个想法来源于PyInstaller,是模仿了它的做法。具体实作:可以用7Zip把自己的库和Python解释器各打一个自解压包,这样解压的工作轻松一些;如果自己的库用Cython编译成.pyd了要想在退出时干净地清理那就麻烦些:Python解释器运行期间会一直持有这个.pyd的句柄,即使你调FreeLibrary()也不行——解决办法:Hook ExitProcess()。
3、绿化Python有个好处:定制性好,在别的电脑上跑时不用担心人家没装Python或者装了有版本冲突。但也有个麻烦的地方:Python.exe的绝对路径被写到了pip.exe里面,but why? 解决办法可参考这里:Create a portable Python with Pip on Windows。不过即使这样做了也还不够彻底,还有其它工作要做。计划有空看看WinPython是怎么做的。
4、写新代码时要思路清晰了再动手,写完之后对着代码在脑子里演练验证一下思路,没疑问了清晰了再运行测试,可减少不少代码调试的时间。