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_DECREFing。 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嵌入代码中的分段错误错误的主要内容,如果未能解决你的问题,请参考以下文章

用C语言实例描述程序中的内聚和耦合

Node,js的模块系统

请你简单阐述用C语言编写一个模块化程序的基本过程

C语言中简单的日志分类打印

C ++获取正在运行的进程的DLL的基地址

在 C 中创建模块系统(动态加载)