使用C对象指针构建PyObject *

问题描述 投票:0回答:1

说我有这个结构:

typedef struct
{
  PyObject_HEAD
  Foo* myFoo;
} PyFoo;

让我们说Foo是:

class Foo
{
public:
  hello()
  {
    std::cout << "Hello\n";
  }
};

我不想将Foo类重新制成python模块,因为它表示库中具有更多函数和变量的类(但这与该问题无关)。我从文档中并没有真正理解如何在C / C ++中使用参数创建PyObject *,更不用说如何使用C / C ++指针作为参数来创建它了。

我要退出本指南:https://docs.python.org/3/extending/newtypes_tutorial.html

我确实有本指南中的dealloc,new和init方法,但是除了对象本身的实例之外,我没有尝试初始化和释放任何值。

此问题类似于Build a PyObject* from a C function?,但我想传递对象指针而不是函数。我正在使用与Create an object using Python's C API相同的方法来创建对象,但是我不知道如何将foo的实例提供给PyObject。

python c++ cpython python-c-api
1个回答
0
投票

所以您可以使用胶囊来做到这一点。

创建对象时:

Foo* myFoo = new Foo();
PyObject* capsule = PyCapsule_New((void*) myFoo, "Foo", NULL);
PyObject* argList = Py_BuildValue("(O)", capsule);
PyObject *obj = PyObject_CallObject((PyObject*) &Foo_PyTypeObject, argList);
Py_DECREF(arglist);
Py_DECREF(capsule); // I don't need python to keep the reference to myFoo

Foo_PyTypeObject应该是您为扩展对象创建的PyTypeObject。

然后我在“新”功能中使用了胶囊。

Foo_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
{
  Foo* self;
  self = (Foo*) type->tp_alloc(type, 0);
  if (self != NULL)
  {
    static char *kwlist[] = {const_cast<char*>("Foo"), NULL};

    PyObject* capsule = NULL;
    PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &capsule);
    self->myFoo = (Foo*) PyCapsule_GetPointer(capsule, "Foo"); // this is the myFoo in the PyFoo struct
    Py_DECREF(capsule);
  }
  return (PyObject*) self;
}
© www.soinside.com 2019 - 2024. All rights reserved.