是否可以从c+中删除python中分配的对象+;? 在我的程序中,我管理C++中的Python对象的引用。也就是说,我的所有类都是从引用的类派生的,该类包含指向相应python对象的指针 引用的类 { 公众: 无符号use_count()常量 { 返回selfptr->ob_refcnt; } void add_ref()常量 { Py_增量(selfptr); } void remove_ref()常量 { Py_减额(自减额); } PyObject*selfptr; };
我使用介入式_ptr来保存从被引用对象派生的对象。这使我能够轻松地保持对C++中所需Python对象的引用,并在必要时访问它们。但是,当Python对象将被从C++删除时,即当我调用py-Restf(SelfpTR)时,我的程序崩溃(仅在Windows HoeWER中),无论是SelfpTr->ObjRefcNt==1。strong>这种方法行吗?是否可以从c+中删除python中分配的对象+;? 在我的程序中,我管理C++中的Python对象的引用。也就是说,我的所有类都是从引用的类派生的,该类包含指向相应python对象的指针 引用的类 { 公众: 无符号use_count()常量 { 返回selfptr->ob_refcnt; } void add_ref()常量 { Py_增量(selfptr); } void remove_ref()常量 { Py_减额(自减额); } PyObject*selfptr; };,c++,python,api,C++,Python,Api,我使用介入式_ptr来保存从被引用对象派生的对象。这使我能够轻松地保持对C++中所需Python对象的引用,并在必要时访问它们。但是,当Python对象将被从C++删除时,即当我调用py-Restf(SelfpTR)时,我的程序崩溃(仅在Windows HoeWER中),无论是SelfpTr->ObjRefcNt==1。strong>这种方法行吗? Upd:我终于解决了程序中的问题。这与物体移除没有直接关系。为了检查最初的问题,我实现了简单的扩展模块,记住对python对象的引用,并根据需要发
Upd:我终于解决了程序中的问题。这与物体移除没有直接关系。为了检查最初的问题,我实现了简单的扩展模块,记住对python对象的引用,并根据需要发布它。这是:
#包括
静态PyObject*myObj;
静态PyObject*acquirePythonObject(PyObject*self,PyObject*obj)
{
printf(“试图获取python对象%p,refcount=%d\n”,obj,obj->ob_refcnt);
myObj=obj;
Py_INCREF(myObj);
printf(“获取的参考文件”);
返回Py_True;
}
静态PyObject*freePythonObject(PyObject*,PyObject*)
{
printf(“尝试释放python对象%p,refcount=%d\n”,myObj,myObj->ob_refcnt);
Py_DECREF(myObj);
printf(“已删除引用”);
返回Py_True;
}
静态PyMethodDef模块方法[]=
{
{“acquirePythonObject”,acquirePythonObject,METH_O,“保持对python对象的引用。”},
{“freePythonObject”,freePythonObject,METH_NOARGS,“python对象的自由引用。”},
{NULL,NULL,0,NULL}
};
PyMODINIT_FUNC初始化模块(无效)
{
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
这个方法行吗
基本上,但是
- 我看不到任何保证
/add\u ref
被调用的次数是正确的(使用RAII将自动执行此操作-可能这就是您的侵入式\u ptr所做的?)remove\u ref
- 如果您尝试过多次
,我不确定Python能保证什么。如果在知道refcount从1变为0时设置删除_ref
,则可以捕捉到这一点selfptr=NULL
- 通过硬崩溃、显式检查或使用
Py\u XDECREF
- 更妙的是,只需使用
即可Py_CLEAR
- 通过硬崩溃、显式检查或使用
最后。。。您是否有任何崩溃转储或诊断信息?请注意,在windows下,在某些情况下,在一个dll中分配和在另一个dll中取消分配将导致崩溃。我不知道是哪个,但可能值得检查一下,这闻起来有点像你的情况。请注意,这在糟糕的windows实现中是一个问题,在c++/pythong中不是一个普遍的问题。@Plasmah我也有同样的感觉,但如果我正确理解python本身通过c api函数()管理堆,因此,如果Python与C运行时的不同版本链接到C++代码,那么分配/解除分配调用应该属于同一个DLL。@ PlasmaHH仍然不理解。若我调用Py_DECREF,我会进入python_27.dll,所以若它在某个地方调用free,它应该从链接python27.dll的c运行时访问该函数。正是我需要的。我说的不对吗?关于上面发布的内容:Python中的分配和释放遍历对象的分配器和释放定位器,由
PyTypeObject
结构中的指针定义。如果它们都指向同一个DLL,则应该没有问题。(如果链接正确,也应该没有问题。)1)是的,intrusive_ptr确保了RAII,我使用了一个类似于boost::intrusive_ptr()的方法。2)我在引用的类中进行了安全检查,只是删除了它们以增加可读性。我终于发现了问题,崩溃是由其他第三方模块引起的,它是由对象破坏触发的。虽然我花了很多时间来研究它,但我甚至在cpp中编写了一个发布python对象的小演示。我回家后会把它放在这里,并在linux中验证它。