嵌入式python在第二次运行时崩溃

时间:2019-04-15 16:17:00

标签: python cpython

要在我的cpp应用程序中嵌入python,我在Windows上使用VS2017的MSVC v141(MSV v.1916 32位)编译了cpython 3.7.3。 生成的代码位于PCBuild / win32中。

应用程序需要修改sys.path才能从应用程序目录的子文件夹中找到模块。那是我注意到无法解释的崩溃的地方。以下脚本在第一次运行时有效,但在第二次运行时无效。第二次运行使应用程序崩溃。这与import语句有关。我可以轻松地调用真正的opencv函数,但将其作为最小示例删除了。 此外,如果我从搜索路径中删除C:\Python\cpython3.7.3\PCbuild\win32,该脚本也不会崩溃,但是该脚本当然不会执行应有的作用。

#!/usr/bin/env python3

import sys
sys.path = ['', 'C:\Python\cpython3.7.3', 'C:\Python\cpython3.7.3\Lib', 'C:\Python\cpython3.7.3\PCbuild\win32', 'C:\Python\cpython3.7.3\Lib\site-packages']

import cv2 # crash on 2nd run
import numpy # crash on 2nd run
import os # always works
import glob # always works

不幸的是,我无法在运行python时调试应用程序,因为python由于缺少编码而无法初始化。仅释放模式有效。 似乎内置模块有效,而通过pip(文件夹站点软件包)下载的模块无效。


步骤

  • 从上方从C:/temp/import_crash_on_2nd_run.py保存python脚本
  • 将cpython下载到C:/python/cpython3.7.3
  • 使用以下内容将build.bat放入C:/ python并运行该文件。建筑大约需要5分钟。

build.bat :(发布版本;为调试添加-d)

 cd cpython3.7.3
 cd PCbuild
 cmd /c build.bat
 pause

为了执行脚本,我创建了这个最小的示例。这不是我的原始代码,但是在第二次运行时也会崩溃,我希望原因是相同的。

main.cpp

#include <Python.h>
#include <fstream>
#include <sstream>
#include <string>

int runScript(const std::string &script){    
    const char *script_ = {script.c_str()};
    Py_Initialize();
    PyRun_SimpleString(script_);
    Py_Finalize();
    return 0;
}


int main(int argc, char *argv[])
{
    std::string scriptpath = "C:\\temp\\import_crash_on_2nd_run.py";
    std::ifstream t(scriptpath);
    std::stringstream buffer;
    buffer << t.rdbuf();

    // maxCount=2 -> crash
    int maxCount = 1;
    for ( int count = 0; count < maxCount; count++ ){
        runScript(buffer.str());
    }
}

更新:

这是一个错误。 https://github.com/numpy/numpy/issues/8097的某人注意到,如果您不致电Py_Finalize,它在连续导入时不会崩溃。完全没有。从使用的库中不确定这是python的错误还是质量差。

0 个答案:

没有答案