我正在尝试使用Py_CompileString()和调用一些python代码PyEval_EvalCode().它工作正常,但当Python代码包含错误Py_Finalize()时.
Py_Initialize();
PyObject* code = Py_CompileString("pprint('Hello World')", "", Py_file_input);
PyObject* m = PyImport_AddModule("__main__");
PyObject* d = PyModule_GetDict(m);
Py_DECREF(m);
PyObject* r = PyEval_EvalCode(code, d, d);
Py_DECREF(d);
if (!r)
PyErr_Print();
Py_DECREF(code);
Py_Finalize();
Run Code Online (Sandbox Code Playgroud)
输出符合预期:
Traceback (most recent call last):
File "", line 1, in <module>
NameError: name 'pprint' is no defined
Run Code Online (Sandbox Code Playgroud)
但是在调用Py_Finalize()程序崩溃的时候.如果我将第3行更改为
PyObject* code = Py_CompileString("print('Hello World')", "", Py_file_input);
Run Code Online (Sandbox Code Playgroud)
程序运行并终止正常.这里出了什么问题?
如果我在gdb中运行该程序,我得到这个输出:
Windows:
Program received signal SIGSEGV, Segmentation fault.
0x1e01a030 in python32!PyType_IsSubtype () from C:\Windows\SysWOW64\python32.dll
Linux:
Program received signal SIGSEGV, Segmentation fault.
0xb7ef17bb in visit_decref (op=0xb78c87ec, data=0x0) at Modules/gcmodule.c:321
321 Modules/gcmodule.c: File or Directory not found.
in Modules/gcmodule.c
Run Code Online (Sandbox Code Playgroud)
小智 5
这种失败的实际原因并不是你Py_DECREF太早打电话.这就是你要打电话的!
PyImport_AddModule返回一个借来的引用.这意味着Py_DECREF除非您实际控制了它(例如通过增加引用计数Py_INCREF),否则根本不允许您进行调用.
Python会自动垃圾收集模块引用Py_Finalize.无需采取其他行动.