使用 C API 创建导入的 python 类的实例

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

我想使用 C API 创建 Python 类的实例。

我的具体用例是 PySerial 对象。我的 Python 代码是:

import serial
test = serial.Serial()

我找不到任何这样做的线索或教程。 我认为唯一知道的是将其声明为我的 pyproject.toml 中的依赖项,并使用

PyImport_*
函数以某种方式导入它。

我当前的代码看起来像这样:

...
/*! Python Module Initialization Function
 * This function will be called when importing the Module to the Python Interpreter.
 * In this function all Python Objects and Constants are added to the Python Module.
 */
PyMODINIT_FUNC PyInit_Module(void)
{
    PyObject *m;
    // Check SubClass Type
    if (PyType_Ready(&SubClassType) < 0) return NULL;

    m = PyModule_Create(&Module_module);
    if (m == NULL) return NULL;

    /* Adding SubClass Class */
    Py_INCREF(&SubClassType);

    if (PyModule_AddObject(m, "SubClass", (PyObject *)&SubClassType) < 0) {
        Py_DECREF(&SubClassType);
        Py_DECREF(m);
        return NULL;
    }

    PySerialObject = PyImport_ImportModule("serial");
    if (PySerialObject == NULL) {
        Py_DECREF(&SubClassType);
        Py_DECREF(m);
        return NULL;
    }

    return m;
}
...
/*! SubClass new
 * Creating new SubClass Python Object
 */
static PyObject *SubClass_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    SubClassObject *self;
    self = (SubClassObject *)type->tp_alloc(type, 0);
    self->serial = NULL;
    if (self != NULL) {
                //self->serial = PyObject_CallNoArgs((PyObject*)Py_TYPE(PySerialObject));
        self->serial = PyObject_CallOneArg((PyObject *)Py_TYPE(PySerialObject), Py_BuildValue("serial.Serial()"));
        if (self->serial == NULL) return NULL;
    }
    return (PyObject *)self;
}

我的目标是在我的 C 代码中使用

serial.Serial()
Python 对象。

c python-3.x cpython python-c-api
1个回答
0
投票

我发现我的答案在答案的指导下对我有用有什么方法可以使用 C API 创建 NumPy 矩阵吗?

线索是首先导入模块,然后从其属性中获取对象。使用此对象,您可以实例化更多实例。在代码中它看起来像这样:

/*! Python Module Initialization Function
 * This function will be called when importing the Module to the Python Interpreter.
 * In this function all Python Objects and Constants are added to the Python Module.
 */
PyMODINIT_FUNC PyInit_Module(void)
{
    PyObject *m;
    // Check SubClass Type
    if (PyType_Ready(&SubClassType) < 0) return NULL;

    m = PyModule_Create(&Module_module);
    if (m == NULL) return NULL;

    /* Adding SubClass Class */
    Py_INCREF(&SubClassType);

    if (PyModule_AddObject(m, "SubClass", (PyObject *)&SubClassType) < 0) {
        Py_DECREF(&SubClassType);
        Py_DECREF(m);
        return NULL;
    }

    PySerial = PyImport_ImportModule("serial");
    if (PySerial == NULL) {
        Py_DECREF(&SubClassType);
        Py_DECREF(m);
        return NULL;
    }
    PySerialObject = PyObject_GetAttrString(PySerial, "Serial");
    if (PySerialObject == NULL) {
        Py_DECREF(&SubClassType);
        Py_DECREF(&PySerial);
        Py_DECREF(m);
        return NULL;
    }

    return m;
}
...
/*! SubClass new
 * Creating new SubClass Python Object
 */
static PyObject *SubClass_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    SubClassObject *self;
    self = (SubClassObject *)type->tp_alloc(type, 0);
    if (self == NULL) return NULL;
    self->serial = NULL;
    self->serial = PyObject_CallNoArgs(PySerialObject);
    if (self->serial == NULL) return NULL;
    return (PyObject *)self;
}

对于我建议的最小解决方案

PyObject *serial = PyImport_ImportModule("serial");
PyObject *serialObject = PyObject_GetAttrString(serial, "Serial");
PyObject *my_serial = PyObject_CallNoArgs(serialObject);

但是您当然可以使用任何

PyObject_Call*
功能。

我想将其留在这里,以便未来的开发人员可以轻松地搜索这个确切的问题。

© www.soinside.com 2019 - 2024. All rights reserved.