[英]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.