简化Python解释环境的安装

问题描述

在C++和Python混合编程中,在软件发布的时候需要将python的解释器打包到安装程序中,为了提高用户体验,我们需要让用户感觉不到python的安装,如果用户已经安装有python的环境,我们也要保证不影响现有的系统。

解决方案

在Python2.5以后,python支持从zip文件中读取python脚本文件,支持读取py,pyc,pyo,不支持读取pyd,因此

我们可以将python的标准库编译以后打包到一个zip文件中,在C++中调用python脚本的时候,将zip文件加入到sys.path的搜索路径中来完成。

  1. 将python的标准库的脚本文件目录C:/Python25/Lib中的脚本文件copy到一个指定的目录,然后我们删除掉一些不用的库文件比如msilib,complier等(此步不熟悉可以不要省去删除多余文件)。
  2. 将脚本编译为优化后的文件 python -O -m compileall destdir,然后删除所有冗余的py和pyc, del /S /Q "%1/*.pyc" "%1/*.py " ( %1 表示目标文件夹 )
  3. 将文件压缩成zip格式 "%WINRAR_DIR%/WinRar" a -r -m5 -tk "python25.zip"  "*"
  4. 我们自己的py文件可以按照同样的方法压缩到src.zip中
  5. 将python的pyd文件(Windows默认是C:/Python25/DLLs)复制到目标文件夹python25_dll中
  6. 将python25.dll复制到应用程序的搜索路径中
  7. 在C++中调用Python的C API设置python库的搜索路径,这样我们就可以就可以通过Python C API进行混合语言的编程,在部署的时候不需要单独按照python安装程序

    char buffer[1024] = { 0 };
    Py_Initialize();
    PyRun_SimpleString( "import sys" );

    //获取当前路径,如果是GUI程序有可能会改变程序的当前工作目录,如果是服务器
    //程序一般当前的工作目录就是二进制文件所在的目录
#ifdef WIN32
    char achCwdBuf[PATH_MAX] = {0};
    if( NULL != GetModuleFileName(NULL, achCwdBuf, PATH_MAX) )
#else
    if( NULL != ACE_OS::getcwd(achCwdBuf, PATH_MAX) )
#endif // end of ifdef WIN32
    {       
        string strCwd = achCwdBuf;
        strCwd = strCwd.substr( 0, strCwd.find_last_of( "///" ) );
        string strStdZip = strCwd;
        strStdZip += "//python25.zip";
        sprintf( buffer, "sys.path += ['.', r'%s', r'%s//python25_dlls', r'%s//src.zip', r'%s//python_script']",
            strStdZip.c_str(), strCwd.c_str(), strCwd.c_str() );
        PyRun_SimpleString( buffer );
    }

你可能感兴趣的:(Python)