3

我有两个不同的 Python 扩展模块;我们称它们为 A 和 B。模块 A 包含一个称为容器的存储类类型,我想在模块 B 中将其用作类方法的返回类型。

我似乎找不到任何关于我应该如何执行此操作的文档。我大致按照这篇文章来创建模块/类,除了我没有将所有方法声明为静态的,所以它们可以访问: http: //nedbatchelder.com/text/whirlext.html

那么我的问题是,如何创建一个容器实例,我可以将其作为模块 B 中类方法的 PyObject* 返回值传回?容器定义如下所示:

typedef struct {
    PyObject_HEAD

    storageclass* cnt_;
} container;

我尝试在相关方法中简单地执行以下操作,其中 container_init 是我为容器类注册为 tp_init 的方法:

pycnt::container* retval;
pycnt::container_init(retval, NULL, NULL);
return (PyObject*)retval;

然而,根据 Python 解释器,我正在取回调用该方法的类。(即,myclassinstance.mymethod() 正在返回 myclassinstance)。

我显然是以错误的方式解决这个问题,但我不知道正确的方法是什么。有什么建议么?只是为了切断任何人的建议——不,我对使用 SWIG 或 Boost::Python 不感兴趣。我已经尝试过了,容器的底层存储类也不能很好地使用(SWIG 甚至无法解析它)。到目前为止,自己进行扩展非常轻松,但我对这个感到难过。

4

1 回答 1

3

你的问题是它type->tp_init没有做你想要的。type->tp_init在分配对象以进行实例化后调用。您首先必须使用 分配对象type->tp_new,然后将该对象作为第一个参数传递给type->tp_init. 由于您将未初始化的指针传递给tp_init,因此所有赌注都已关闭。但是,您通常不会直接调用任何一个函数,而是调用PyObject_Call*()类型对象本身的其中一个函数来创建一个新实例。或者提供一个普通的 C 函数来创建一个新实例, a la PyFoo_New()

也就是说,在两个扩展模块之间进行互通的常用方法是通过 Python API 来实现。如果您希望模块 B 导入和使用模块 A,则调用PyImport_Import()以获取模块对象,PyObject_GetAttrString()获取您关心的类型对象,并PyObject_Call*()实例化它之一。任何你想存储指向该类型的指针的地方,你只需要一个PyObject *.

于 2010-01-26T00:06:04.290 回答