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

14 投票
1 回答
4585 浏览
提问于 2025-04-17 00:29

我有一个兼容性库,它使用SWIG来访问一个C++库。我希望能在这个层级里创建一个用SWIG包装的Python对象,而不是接受C++对象作为参数或返回一个C++对象。也就是说,我想要一个指向这个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 个回答

11

当你使用 SWIG_NewPointerObj 创建新的指针对象时,可以传入一些标志位:

SWIG_POINTER_OWN
SWIG_POINTER_NOSHADOW

如果设置了 SWIG_POINTER_OWN,这样在 Python 指针被销毁时,底层的 C++ 类的析构函数会被调用。默认情况下,析构函数是不会被调用的。具体可以查看 内存管理 的相关内容。

根据你的使用情况,其实你根本不需要设置任何标志位。

从我看到的源代码来看,如果设置了 SWIG_POINTER_NOSHADOW,那么返回的就是一个基本的封装指针。在 Python 中你将无法访问成员变量。你得到的只是一个不透明的指针。

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

撰写回答