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);
}

私はこれを理解するために何週間も取り組んできましたが、何が間違っているのかはまだわかりません. もう 1 つのことは、Python 拡張機能チュートリアルの必要最小限の例が、私の場合と同じようにクラッシュすることですが、後の例ではクラッシュしません。ここで何が間違っていますか?

(おなじみのように思われるかもしれませんが、私は 1 週間前にこの質問をして、「タンブルウィード」バッジを取得しました。だから...)

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 に答える