3

我有一个使用 Python 回调的 C++ 库。回调,即 PyObject*,存储在 UnaryFunction 类的对象中,构造函数 Py_INCREF 对其进行引用。析构函数 Py_XDECREFs 它。那就是问题所在。解释器在该 DECREF 上出现段错误。

我的解决方案是不 DECREF 它,但这似乎是错误的。INC/DEC 函数引用计数的正确方法是什么,更重要的是,为什么解释器在有其他实时引用时尝试 GC 函数体?

编辑:在 Linux 而不是段错误上,我得到一个断言失败,上面写着:

python: Objects/funcobject.c:442: func_dealloc: Assertion 'g->gc.gc_refs != (-2)' failed.

4

2 回答 2

1

崩溃并不一定意味着它正在尝试 GC 使用过的对象。这也可能意味着您在没有解释器锁的情况下调用 python 代码。

在析构函数中调用 Py_XDECREF 让我认为你有这样的事情:

void MyCallback(myfunc, myarg)
{
    ...
    PyGILState_STATE gilstate = PyGILState_Ensure();
    try {
            myfunc(myarg);
    } catch (...) {
        ...
    }
    PyGILState_Release(gilstate);

    // myfunc goes out of scope here --> CRASH because we no longer own the GIL
}

使用简单的解决方案:

...
try {
    scopefunc = myfunc;
    myfunc = emptyfunc();
    scopefunc(myarg);
} ...
于 2011-09-08T03:47:07.423 回答
0

看来 Py_INCREF 实际上并没有增加引用计数。

于 2011-09-09T00:12:35.850 回答