【发布时间】:2019-05-29 13:33:35
【问题描述】:
我想从 OMNeT++ 简单模块中的 C++ 代码调用 Python 函数。
我使用 gdb 调试了代码。它通过了所有行,但最后
在Py_Finalize(); 之后发生分段错误。
我发现以下issue on GitHub 描述了相同的问题。 但这并没有帮助我解决问题。
double result=0;
// 1) Initialise python interpretator
if (!Py_IsInitialized()) {
Py_Initialize();
//Py_AtExit(Py_Finalize);
}
// 2) Initialise python thread mechanism
if (!PyEval_ThreadsInitialized()) {
PyEval_InitThreads();
assert(PyEval_ThreadsInitialized());
}
PyGILState_STATE s = PyGILState_Ensure();
PyRun_SimpleString("import sys; sys.path.append('/home/mypath/')");
PyObject *pName = PyUnicode_DecodeFSDefault((char*)"integrationTest");
PyObject* pModule = PyImport_Import(pName);
if (pModule != NULL)
{
PyObject* pFunction = PyObject_GetAttrString(pModule, (char*)"calculateExecutionTime");
/// changement will be held in this level Args and function result.
PyObject* pArgs = PyTuple_Pack(2,PyFloat_FromDouble(2.0),PyFloat_FromDouble(8.0));
PyObject* pResult = PyObject_CallObject(pFunction, pArgs);
result = (double)PyFloat_AsDouble(pResult);
///////
}
// Clean up
PyGILState_Release(s);
Py_DECREF(pName);
Py_DECREF(pModule);
Py_Finalize();
【问题讨论】:
-
PyObject_GetAttrString(pModule (char*)"calculateExecutionTime");不应该是合法的。您的真实代码中是否有逗号,或者编译器是否接受了真正奇怪的东西?此外,您没有检查NULL的返回值(在PyObject_CallObject调用中尤其重要,您将忽略引发的任何异常并试图将可能的NULL返回解释为指向PyFloat的合法指针) 或其他错误返回(例如,PyFloat_AsDouble返回-1.0并设置失败异常)。 -
附加问题:您在发布 GIL 后是
Py_DECREFing。 GIL 的主要目的是保护引用计数操作;如果您不持有 GIL,则不允许以任何方式修改引用计数。诚然,如果不涉及线程,这不太可能成为问题,但这只是另一个可能的问题来源。 -
我的真实代码在 PyObject_GetAttrString(pModule,(char*)"calculateExecutionTime"); 中包含一个逗号。我会检查我的返回值。感谢您的 cmets。
标签: python c++ python-3.x omnet++ python-c-api