SWIG_NewPointerObj 的最后一个参数是啥意思?

Posted

技术标签:

【中文标题】SWIG_NewPointerObj 的最后一个参数是啥意思?【英文标题】:what does the last argument to SWIG_NewPointerObj mean?SWIG_NewPointerObj 的最后一个参数是什么意思? 【发布时间】:2011-08-28 19:23:47 【问题描述】:

我有一个使用 SWIG 访问 C++ 库的兼容性库。我会发现能够在这一层内创建一个 SWIG 包装的 Python 对象很有用(而不是接受 C++ 对象作为参数或返回一个)。 IE。我想要指向 SWIG 包装的 C++ 对象的 PyObject*

我发现SWIG_NewPointerObj 函数正是这样做的。 SWIG 生成的 xx_wrap.cpp 文件使用此函数,但它也可在 swig -python -external-runtime swigpyrun.h 发出的标头中使用

但是,我找不到任何关于此函数的最后一个参数的参考。它似乎指定了对象的所有权,但没有文档说明每个选项的含义(甚至它们都是什么)。 似乎以下是可接受的值:

0 SWIG_POINTER_OWN SWIG_POINTER_NOSHADOW SWIG_POINTER_NEW = OWN + NOSHADOW SWIG_POINTER_DISOWN(我不确定 SWIG_NewPointerObj 是否接受) SWIG_POINTER_IMPLICIT_CONV(我不确定 SWIG_NewPointerObj 是否接受)

我想创建一个仅在包装层中使用的对象。我想用我自己的指向 C++ 对象的指针创建它(这样我就可以更改 C++ 对象的值并将其反映在 Python 对象中。我需要它以便可以将它传递给 Python 回调函数。我想在程序的整个生命周期中保留这个实例,这样我就不会浪费时间为每个回调创建/销毁相同的对象。哪个选项合适,我该怎么Py_INCREF

【问题讨论】:

+1,好问题,而且比我上次看 swig 时的选择多了一些! @eryksun,但我不希望 Python 在我完成之前收集该对象,但我也不希望在我有机会 INCREF 之前收集它。我也不希望 SWIG 摧毁它。 【参考方案1】:

当您使用SWIG_NewPointerObj 创建新的指针对象时,您可以传递以下标志:

SWIG_POINTER_OWN
SWIG_POINTER_NOSHADOW

如果设置了 SWIG_POINTER_OWN,则当 Python 指针最终确定时,将调用底层 C++ 类的析构函数。默认情况下,不会调用析构函数。见Memory Management

对于您的用例,您根本不需要设置任何标志。

从我在源代码中可以看到,如果设置了 SWIG_POINTER_NOSHADOW,则返回一个基本的包装指针。您将无法在 Python 中访问成员变量。你所拥有的只是一个不透明的指针。

参考:/usr/share/swig/2.0.7/python/pyrun.swg

【讨论】:

好消息。 SWIG_NewPointerObj 的结果是否需要 INCREFed? SWIG_NewPointerObj 返回一个已经有一个引用的 Python 对象。所以不需要 INCREF。看看 swigpyrun.h。 SWIG_NewPointerObj 别名为 SWIG_Python_NewPointerObj,后者又调用 PyObject_New。

以上是关于SWIG_NewPointerObj 的最后一个参数是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

简单的函数实参形参默认值的定义

MyBatis两种传参方式的区别

Go语言:变参函数

Go语言 可变参数(变参函数)

shell脚本入参包含感叹号怎么处理

cpp►变参函数与回调函数