python - 在 Python C API 中使用多个模块/类型?

标签 python c binding python-c-api python-extensions

我有两个不同的 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 甚至无法解析它)。到目前为止,我自己进行扩展非常轻松,但我在这个问题上遇到了困难。

最佳答案

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

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

关于python - 在 Python C API 中使用多个模块/类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2136337/

相关文章:

c# - 是否有任何事件表明所有依赖属性都已加载?

python - 使用 Pyomo 的旅行推销员

python - Tensorboard 中重复的所有变量是什么?

CS50 类(class) pset5 : scale bitmap in C

c++ - 为什么多线程更慢?

c# - ObservableCollection 更新时如何更新 UI?

python - 交换两个数字的替代方法

python - Keras LSTM 对于单输入有不同的输出

c++ - 声明由指针指示的类型的变量

WPF 绑定(bind) - StringFormat - 不格式化