Omnet ++简单模块的C ++代码中python嵌入代码中的分段错误错误
Posted
技术标签:
【中文标题】Omnet ++简单模块的C ++代码中python嵌入代码中的分段错误错误【英文标题】:Segmentation fault error in python embedded code in C++ code of Omnet++ simple module 【发布时间】: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_DECREF
ing。 GIL 的主要目的是保护引用计数操作;如果您不持有 GIL,则不允许以任何方式修改引用计数。诚然,如果不涉及线程,这不太可能成为问题,但这只是另一个可能的问题来源。
我的真实代码在 PyObject_GetAttrString(pModule,(char*)"calculateExecutionTime"); 中包含一个逗号。我会检查我的返回值。感谢您的 cmets。
【参考方案1】:
问题发生在python解释器第一次初始化/取消初始化之后。在 OmneT++ 模拟期间发生的事情是初始化/取消初始化/重新初始化/... Python 解释器。但是,Numpy 不支持这个;
所以,我通过在 initialize() 方法的模拟开始时只初始化一次 python 解释器来解决这个问题。然后,我调用了 Py_Finalize();在析构函数中。
【讨论】:
好的。但是在您的问题中没有任何线索表明您可能会多次初始化和完成 Python(并且您链接到的 github 问题以及您所说的“没有帮助”实际上表示不支持)。请阅读关于询问minimal reproducible example的帮助,并在下一次关注它 没错,因为我在 OmneT++ 模拟的特殊情况下使用 python 嵌入式代码。它不是经典的 C++ 程序。它由模拟事件控制,之后我理解了问题,然后 github 链接很有帮助。一开始,我并不了解python解释器机制。谢谢你的链接,我下次会关注它。以上是关于Omnet ++简单模块的C ++代码中python嵌入代码中的分段错误错误的主要内容,如果未能解决你的问题,请参考以下文章