繁体   English   中英

从 C++ 调用 Python 代码给出了意外数量的引用

[英]Calling Python code from C++ gives unexpected number of references

我正在运行下面的 C++ 代码,如果我注释掉Py_XDECREF行,它工作正常。 但是,我想在这种情况下它会导致内存泄漏。 Py_XDECREF行被注释时,代码执行行为异常。 首先,我不明白参考文献的数量。 例如,为什么有七个对 pName 的引用? 其次,为什么在使用Py_XDECREF时会出现负引用计数错误? 据我了解Py_XDECREF在这方面应该是安全的,并且只有在我使用Py_DECREF时才会出现当前错误? 第三也是最重要的一点:如何更改代码以使其正常工作?

当执行行Py_XDECREF(pDict); 我收到以下错误:

D:\a\1\s\Include\object.h:497: _Py_NegativeRefcount: Assertion failed: object has negative ref count
<object at 0000018CA6726410 is freed>
Fatal Python error: _PyObject_AssertFailed: _PyObject_AssertFailed
Python runtime state: initialized
Current thread 0x000086b0 (most recent call first):
<no Python frame>

这是代码:

#include <Python.h> 
#include <stdio.h>
#include <iostream>
#include <sstream>

int main(int argc, char** argv) {

    // 1) initialize Python
    Py_Initialize();
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append(\".\")");
    PyRun_SimpleString("print(sys.path)");

    // 2) Import the python module
    PyObject* pName = PyUnicode_FromString("module1");
    assert(pName != NULL);
    PyObject* pModule = PyImport_Import(pName);
    assert(pModule != NULL);

    // 3) Get a reference to the python function to call
    PyObject* pDict = PyModule_GetDict(pModule);
    assert(pDict != NULL);
    PyObject* pFunc = PyDict_GetItemString(pDict, (char*)"getInteger");
    assert(pFunc != NULL);

    // 4) Call function
    PyObject* pValue = PyObject_CallObject(pFunc, NULL);

    Py_XDECREF(pValue);
    Py_XDECREF(pFunc);
    Py_XDECREF(pDict);
    Py_XDECREF(pModule);
    Py_XDECREF(pName);

    Py_Finalize();

导入的模块称为module1.py并具有以下内容:

def getInteger():
    print('Python function getInteger() called')
    c = 100*50/30
    return c

PyModule_GetDict返回借用的引用 您不应该减少借用引用的引用计数,因此错误完全是预料之中的:引用计数不能减少,因为它已经为零。

但是,您可以直接使用PyObject_GetAttrString(pModule, "getInteger")而不是通过pDict来简化它。

您还应该编写正确的错误处理,因为assert仅适用于调试构建,而在发布模式下变为空操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM