我正在寻找一种让Python C函数在其模块中注册其他Python C函数的方法。
通常使用以下函数在共享库中静态声明函数:
Py_InitModule(module_name, functions);
我在cpython中看一下Py_InitModule实现,并尝试:
PyModule_GetDict(module)
PyCFunction_NewEx(&method, (PyObject*)NULL, n)
PyDict_SetItemString(d, method.ml_name, v) != 0
然而,当我尝试调用新函数时,它会出现故障。
我做错了什么? 甚至可以用CPython做这样的事情吗?
更确切地说,这是一个完整的例子:
static int load_extra_methods(void)
{
PyMethodDef module_methods[] = {
{
"my_new_method",
my_new_method,
METH_VARARGS,
},
/* possibly more functions here */
};
const char *name = "module_name";
PyObject *d = PyModule_GetDir(_G.pymodule);
PyObject *n;
if(_Py_PackageContext != NULL) {
char *p = strrchr(_Py_PackageContext, '.');
if (p != NULL && strcmp(name, p + 1) == 0) {
name = _Py_PackageContext;
_Py_PackageContext = NULL;
}
}
n = PyString_FromString(name);
for (int i = 0; i < countof(module_methods); i++) {
PyMethodDef method = module_methods[i];
PyObject *v = PyCFunction_NewEx(&method, (PyOBject*)NULL, n);
if (v == NULL) {
Py_DECREF(n);
}
if (PyDict_SetItemString(d, method.ml_name, v) != 0) {
Py_DECREF(v);
Py_DECREF(n);
return -1;
}
Py_DECREF(v);
}
return 0;
Py_DECREF(n);
}
上面的这个函数是由先前使用通常的Py_InitModule3函数公开的另一个函数调用的。 上面的代码大量借用了CPython实现本身(Python / modsupport.c Py_InitModule4)。
修改
我错放了Py_DECREF(n); (现在在示例代码中修复)。 现在我有了:
SystemError: ../Objects/methodobject.c:120: bad argument to internal function