1

我遇到了一个问题,只是想弄清楚。在event_init中,我发现PyModule_AddObject无论我对类型和模块创建做什么,调用都会失败。为了进一步隔离问题,我发现只有添加了我的自定义类型才会导致它崩溃(添加Py_True运行正常),并且实际上是模块字典的操作导致它崩溃(内部调用PyDict_SetItem

#include <Python.h>
#include <structmember.h>

struct pyEventProxy{
    PyObject_HEAD
};

static PyObject* pyKey_on(PyObject*,PyObject* args,PyObject* kwargs){
    /* ... */
}

static PyMethodDef pyKey_Methods[]={
    {"on",(PyCFunction)pyKey_on,METH_STATIC,"Bind a keyboard event handler for one or more events."},
    {NULL}
};

static PyTypeObject pyKey_Type={
    PyVarObject_HEAD_INIT(NULL,0)
    "key",
    sizeof(pyEventProxy),
    0,
    0,
    0,                         /* tp_print */
    0,                         /* tp_getattr */
    0,                         /* tp_setattr */
    0,                         /* tp_reserved */
    0,                         /* tp_repr */
    0,                         /* tp_as_number */
    0,                         /* tp_as_sequence */
    0,                         /* tp_as_mapping */
    0,                         /* tp_hash  */
    0,                         /* tp_call */
    0,                         /* tp_str */
    0,                         /* tp_getattro */
    0,                         /* tp_setattro */
    0,                         /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT,
    "Proxy object to access specific event functions.",
    0,                          /* tp_traverse */
    0,                          /* tp_clear */
    0,                         /* tp_richcompare */
    0,                         /* tp_weaklistoffset */
    0,                         /* tp_iter */
    0,                         /* tp_iternext */
    pyKey_Methods,             /* tp_methods */
};

static PyModuleDef pyEvent_Module={
    PyModuleDef_HEAD_INIT,
    "event",
    "Interact with Sandblox's event handling.",
    -1,
    0,
    0,
    0,
    0,
    0
};

//Function called in another file to initialize the module
void event_init(){
    printf("Initializing key proxy type\n");
    if(PyType_Ready(&pyKey_Type)<0){
        printf("Key preparation failed\n");
        return;
    }

    printf("Creating module\n");
    PyObject* module=PyModule_Create(&pyEvent_Module);
    if(!module){
        return;
    }

    printf("Adding key proxy\n");
    Py_INCREF(&pyKey_Type);
    //This crashes
    PyModule_AddObject(module,"key",(PyObject*)&pyKey_Type);
}

几个星期以来,我一直在努力解决这个问题,但我仍然无法理解到底出了什么问题。另一件事是,Python 扩展教程中的简单示例就像我的一样崩溃,但不会用于后面的示例。我在这里做错了什么?

(如果这看起来很熟悉,我一周前问了这个问题并得到了一个“风滚草”徽章。所以......)

4

1 回答 1

1

在 Python 3.x 中,模块初始化函数必须返回模块对象。你的代码不会那样工作。适合您的模块的 init 函数如下所示:

PyMODINIT_FUNC
PyInit_event(void) {
    PyObject *module;
    module = PyModule_Create(&pyEvent_Module);
    ...
    return module;
}
于 2013-09-08T17:31:46.847 回答