为什么Python/C API在PyRun_SimpleFile时崩溃?

18 投票
7 回答
20191 浏览
提问于 2025-04-16 03:47

我最近在尝试把不同的脚本语言嵌入到一个C++应用程序中,目前我在试验Stackless Python 3.1。我找了几个教程和例子,虽然不多,但我想从应用程序中运行一个简单的脚本。

Py_Initialize();

FILE* PythonScriptFile = fopen("Python Scripts/Test.py", "r");
if(PythonScriptFile)
{
    PyRun_SimpleFile(PythonScriptFile, "Python Scripts/Test.py");
    fclose(PythonScriptFile);
}

Py_Finalize();

但是奇怪的是,运行这段代码时出现了访问违规的问题,具体是在:

    PyRun_SimpleFile(PythonScriptFile, "Python Scripts/Test.py");

我在网上查找了其他人是否有类似的问题,只找到一个。他们的解决办法是一个变通方法,但似乎只在旧版本的Python中可行:创建一个Python文件对象,并将这个文件对象的FILE*返回给PyRun_SimpleFile。不过,这种函数调用在Python 3.1的API中并不存在,Python 3.1的API是通过文件描述符来创建文件对象并返回文件描述符,但PyRun_SimpleFile函数仍然需要一个FILE*

我现在不知道怎么从文件中运行任何脚本,除了手动把整个文件加载到内存中,然后作为一个巨大的字符串来运行,这显然不是个实际的解决方案。

这是怎么回事呢?如果API内部有错误,我该如何完成这个任务?

更新: 我已经成功从源代码构建了Stackless Python 3.1,但崩溃的问题依然没有改变,尽管我使用的是相同的C运行时库。我的项目和Stackless Python 3.1的源代码都是用Visual Studio 2010的C++编译器和C运行时构建的。我现在完全不知道该怎么解决这个问题,除了修改Python以使用文件名而不是FILE*,这也是个糟糕的变通办法。

7 个回答

5

你的代码在我安装的Python 2.6版本上运行得很好。我还从源代码编译了stackless 3.1.2,它也运行得不错。这是在Ubuntu 10.04上用g++ 4.4.3编译的。如果你是在Windows上,建议你检查一下stackless和你的代码是否使用了相同的C运行时环境。

13

我遇到了类似的崩溃问题,然后我做了以下操作:

   PyObject* PyFileObject = PyFile_FromString("test.py", "r");
   PyRun_SimpleFileEx(PyFile_AsFile(PyFileObject), "test.py", 1);

需要注意的是,这是在python 2.7中进行的。我不知道在3.x版本中API有没有变化。

15

在Python 3上,这对我有效:

 PyObject *obj = Py_BuildValue("s", "test.py");
 FILE *file = _Py_fopen_obj(obj, "r+");
 if(file != NULL) {
     PyRun_SimpleFile(file, "test.py");
 }

希望这对你有帮助。

撰写回答