PyModule_AddObject Crashing

PyModule_AddObject Crashing

本文关键字:Crashing AddObject PyModule      更新时间:2023-10-16

我遇到了一个一直在努力解决的问题。在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 typen");
    if(PyType_Ready(&pyKey_Type)<0){
        printf("Key preparation failedn");
        return;
    }
    printf("Creating modulen");
    PyObject* module=PyModule_Create(&pyEvent_Module);
    if(!module){
        return;
    }
    printf("Adding key proxyn");
    Py_INCREF(&pyKey_Type);
    //This crashes
    PyModule_AddObject(module,"key",(PyObject*)&pyKey_Type);
}

我已经花了好几个星期的时间来弄清楚这个问题,但我仍然不知道到底出了什么问题。另一件事是,Python扩展教程中的基本示例和我的一样崩溃,但后面的示例不会崩溃。我在这里做错了什么?

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

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

PyMODINIT_FUNC
PyInit_event(void) {
    PyObject *module;
    module = PyModule_Create(&pyEvent_Module);
    ...
    return module;
}