从c中删除在python中分配的对象可以吗?

前端之家收集整理的这篇文章主要介绍了从c中删除在python中分配的对象可以吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在我的程序中,我管理C中对 python对象的引用.即我所有的类都是从引用类派生的,它包含指向相应python对象的指针.
class Referenced
{
public:
    unsigned use_count() const
    { 
        return selfptr->ob_refcnt;
    }

    void add_ref() const
    {
        Py_INCREF(selfptr);
    }

    void remove_ref() const
    {
        Py_DECREF(selfptr);
    }

    PyObject* selfptr;
};

我使用intrusive_ptr来保存从引用导出的对象.这允许我很容易地保留对C中所需的python对象的引用,并访问它们,无论是否需要.但是,当python对象从C被删除时,即当我调用Py_DECREF(selfptr)时,我的程序是否崩溃(只有在Windows中),无论是selfptr-> ob_refcnt == 1.

更新:我终于想到了我的程序中的问题.它与对象删除没有直接关系.要检查初始问题,我已经实现了简单的扩展模块,记住对python对象的引用,并按需释放它.就这个:

#include <Python.h>

static PyObject* myObj;

static PyObject* acquirePythonObject(PyObject* self,PyObject* obj)
{
    printf("trying to acquire python object %p,refcount = %d\n",obj,obj->ob_refcnt);
    myObj = obj;
    Py_INCREF(myObj);
    printf("reference acquired\n");
    return Py_True;
}

static PyObject* freePythonObject(PyObject*,PyObject*)
{
    printf("trying to free python object %p,myObj,myObj->ob_refcnt);
    Py_DECREF(myObj);
    printf("reference removed\n");
    return Py_True;
}

static PyMethodDef moduleMethods[] =
{
    {"acquirePythonObject",acquirePythonObject,METH_O,"hold reference to python object."},{"freePythonObject",freePythonObject,METH_NOARGS,"free reference to python object."},{NULL,NULL,NULL}
};

PyMODINIT_FUNC initmodule(void)
{
    Py_InitModule("module",moduleMethods);
}

和python脚本:

import module

class Foo:
    def __init__(self):
        print "Foo is created"

    def __deinit__(self):
        print "Foo is destroyed"

def acquireFoo():
    foo = Foo()
    module.acquirePythonObject(foo)

def freeFoo():
    module.freePythonObject()

if __name__ == "__main__":
    acquireFoo()
    freeFoo()

样例在windows和linux中无缝运行.下面是输出.

Foo is created
trying to acquire python object 0x7fa19fbefd40,refcount = 2
reference acquired
trying to free python object 0x7fa19fbefd40,refcount = 1
Foo is destoryed
reference removed

解决方法

Is this approach OK?

基本上,但…

>我看不到任何保证add_ref / remove_ref被称为正确的次数(使用RAII会自动化这个 – 也许这是你的intrusive_ptr?)
>如果你尝试remove_ref太多次,我不知道Python保证什么.如果您设置selfptr = NULL,当您知道refcount从1 – > 0,你可以抓住这个

>通过崩溃或明确检查,或使用Py_XDECREF
>更好,只需使用Py_CLEAR

最后…你有任何崩溃转储或诊断信息?

猜你在找的C&C++相关文章