gpt4 book ai didi

python - 为什么在使用 Python/C API 时会出现此段错误?

转载 作者:行者123 更新时间:2023-12-03 07:04:34 26 4
gpt4 key购买 nike

减少 PyObject* 时出现段错误在我使用 Python/C API 的 C++ 代码中,我不知道为什么。我正在使用 C++ 和 Python 2.7。我正在使用新型类来实现 future 的 Python 3 兼容性。

我的目标是创建一个 C++ 类 MyClass作为 Python 模块中定义的类的包装器。在 MyClass构造函数,我传入 Python 模块的名称,导入模块,定位类(它总是有一个预定义的名称 PyClass ),然后调用该类来创建它的实例。然后我存储结果 PyObject*MyClass以备将来使用。在 MyClass析构函数,我删除了存储的 PyObject*以避免内存泄漏。

就定位类和创建它的实例而言,我已经验证了一切工作正常。我什至验证了我可以使用存储的 PyObject*在其他 MyClass方法,例如,访问 PyClass 中的方法.但是,当析构函数执行 decref 时,会导致段错误。

这是我的代码示例。我也调用Py_Initialize()Py_Finalize()在适当的时候在其他地方,为了简洁起见,我省略了一些错误检查代码:
MyPythonModule.py

class PyClass:
pass
MyClass.h
class MyClass {
public:
MyClass(const char* modulename);
~MyClass();
private:
void* _StoredPtr;
};
MyClass.cpp
#include <Python.h>
#include <iostream>
#include "MyClass.h"

MyClass::MyClass(const char* modulename) {
_StoredPtr = NULL;

PyObject *pName = NULL, *pModule = NULL, *pAttr = NULL;

// Import the Python module.
pName = PyString_FromString(modulename);
if (pName == NULL) {goto error;}
pModule = PyImport_Import(pName);
if (pModule == NULL) {goto error;}

// Create a PyClass instance and store a pointer to it.
pAttr = PyObject_GetAttrString(pModule, "PyClass");
if (pAttr == NULL) {goto error;}
_StoredPtr = (void*) PyObject_CallObject(pAttr, NULL);
Py_DECREF(pAttr);
if (_StoredPtr == NULL) {goto error;}

error:
if (PyErr_Occurred()) {PyErr_Print();}
Py_XDECREF(pName);
Py_XDECREF(pModule);
return;
}

MyClass::~MyClass() {
std::cout << "Starting destructor..." << std::endl;
Py_XDECREF((PyObject*)(_StoredPtr));
std::cout << "Destructor complete." << std::endl;
}

我知道我可以通过省略 Py_XDECREF() 来避免段错误。在析构函数中,但我害怕导致内存泄漏,因为我不明白为什么会发生这种情况。我可以使用 _StoredPtr 似乎特别奇怪成功在其他 MyClass方法,但我不能decref它。

我也尝试过存储 PyObject* MyClass 中导入的模块并坚持到 _StoredPtr之后已减少,但 _StoredPtr decref 仍然是段错误。我尝试注释掉 Py_DECREF(pAttr);行,但这无济于事。

正如我所提到的,我可以在 PyClass 中检索方法。使用 _StoredPtr ,我也尝试将这些存储在 MyClass并在析构函数中取消它们。当我这样做时,我可以 deref _StoredPtr ,但是当我尝试减少方法的 PyObject* 时,它会出现段错误.如果我使用多种方法执行此操作,则始终是导致段错误的最后一个 decref,无论我将它们放入什么顺序。

关于这里发生了什么的任何见解?

最佳答案

这对我有用

#include <Python.h>
#include <iostream>
#include "MyClass.h"

MyClass::MyClass(const char* modulename) {
_StoredPtr = NULL;

PyObject *pName = NULL, *pModule = NULL, *pAttr = NULL;

// Import the Python module.
pName = PyString_FromString(modulename);
if (pName == NULL) {goto error;}
pModule = PyImport_Import(pName);
if (pModule == NULL) {goto error;}

// Create a PyClass instance and store a pointer to it.
pAttr = PyObject_GetAttrString(pModule, "PyClass");
if (pAttr == NULL) {goto error;}
_StoredPtr = (void*) PyObject_CallObject(pAttr, NULL);
Py_DECREF(pAttr);
if (_StoredPtr == NULL) {goto error;}
else{
// do something with _StoredPtr
Py_XDECREF((*PyObject)_StoredPtr)
}
error:
if (PyErr_Occurred()) {PyErr_Print();}
Py_XDECREF(pName);
Py_XDECREF(pModule);
return;
}

MyClass::~MyClass() {}
我基本上将析构函数之外的 XDECREF 移到了使用 PyObject 的函数中。

关于python - 为什么在使用 Python/C API 时会出现此段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34998007/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com