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

我一直在尝试在 C++ 应用程序中嵌入不同的脚本语言,目前我正在尝试 Stackless Python 3.1.我已经尝试了几个教程和示例,但我能找到的很少,尝试从应用程序运行一个简单的脚本.

Py_Initialize();FILE* PythonScriptFile = fopen("Python Scripts/Test.py", "r");如果(PythonScript 文件){PyRun_SimpleFile(PythonScriptFile, "Python Scripts/Test.py");fclose(PythonScriptFile);}Py_Finalize();

出于某种奇怪的原因,运行这段代码会导致访问冲突:

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

我在网上搜索了其他有类似问题的人,但只找到了一个.他们唯一的解决方案是一种似乎只能在旧版 Python 中实现的解决方法:创建一个 Python 文件对象并将 FILE* 从该 Python 文件对象返回到 PyRun_SimpleFile.但是,此类函数调用不可用,Python 3.1 API 从文件描述符创建文件对象并返回文件描述符,但 PyRun_SimpleFile 函数仍然需要 FILE*.

我不知道如何从文件运行任何脚本,除了手动将整个文件加载到内存中并将其作为一个巨大的字符串运行之外,这当然不是一个实用的解决方案.

什么给?如果 API 出现内部错误,我该如何完成此任务?

更新:我已经设法从源代码构建了 Stackless Python 3.1,尽管使用相同的 C 运行时库,但崩溃仍然完全没有改变.我的项目和 Stackless Python 3.1 源代码都是使用 Visual Studio 2010 的 C++ 编译器和 C 运行时构建的.除了修改 Python 以使用文件名而不是 FILE* 之外,我不再知道什么可以解决这个问题.另一个糟糕的解决方法.

解决方案

这对我在 Python 3 上有效:

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

希望有用.

I've been experimenting with embedding different scripting languages in a C++ application, currently I'm trying Stackless Python 3.1. I've tried several tutorials and examples, what few I can find, to try and run a simple script from an application.

Py_Initialize();

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

Py_Finalize();

For some odd reason, running this piece of code results in an access violation at:

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

I've searched online for others with a similar problem and found only one. Their only solution was a workaround that only seems possible in an older version of Python: Creating a python file object and returning the FILE* from that python file object into PyRun_SimpleFile. Such function calls are not available however, the Python 3.1 API creates file objects from a file descriptor and returns file descriptors, but the PyRun_SimpleFile function still requires a FILE*.

I'm at a loss as to how to run any scripts from file, short of loading the entire file into memory manually and running it as a giant string, certainly not a practical solution.

What gives? How can I accomplish this task if the API has an internal error?

Update: I've managed to build Stackless Python 3.1 from the source and yet the crash remains completely unchanged, despite using the same C runtime library. Both my project and the Stackless Python 3.1 source are built with Visual Studio 2010's C++ compiler and C runtime. I no longer have any inkling as to what might solve this problem, short of modifying Python to use a file name and not a FILE*. Another terrible workaround.

解决方案

This works for me on Python 3:

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

I hope It would be useful.

相关文章