PyObject_CallObject 在主函数作用域外调用时崩溃
PyObject_CallObject crashed when called out of main function scope
我正在构建一个简单的模块来包装 C 函数。这个模块的主要功能(test_wrapper
)基本上接收一个python函数并调用它:
#include <Python.h>
static PyObject* test_wrapper(PyObject* self, PyObject* args) {
PyObject* py_handler;
int args_ok = PyArg_ParseTuple(args, "O", &py_handler);
PyObject_CallObject(py_handler, NULL);
return Py_BuildValue("i", 0);
}
static PyMethodDef TestModuleMethods[] = {
{ "test", test_wrapper, METH_VARARGS, NULL },
{ NULL, NULL, 0, NULL }
};
static struct PyModuleDef TestModule = {
PyModuleDef_HEAD_INIT,
"test_module",
NULL,
-1,
TestModuleMethods
};
PyMODINIT_FUNC PyInit_test_module(void) {
return PyModule_Create(&TestModule);
}
上面的代码工作正常。问题是,假设我需要在未来以另一种方式调用传递的 python 函数 (py_handler
),例如通过信号处理程序,现在它需要一个整数作为参数:
PyObject* py_handler;
void handler(int signo) {
PyObject* handler_args = PyTuple_Pack(1, PyLong_FromLong(signo));
PyObject_CallObject(py_handler, handler_args); //seg fault
}
static PyObject* test_wrapper(PyObject* self, PyObject* args) {
int args_ok = PyArg_ParseTuple(args, "O", &py_handler);
//Py_INCREF(py_handler); //adding this didn't work
//calls sigaction to set handler function
return Py_BuildValue("i", 0);
}
通过这样做,PyObject_CallObject 在被 handler
调用时崩溃(段错误)。
我可能在这里遗漏了什么?
如果相关,我正在用 setup.py
构建 .so
。
获取并释放GIL足以解决问题:
void handler(int signo) {
PyGILState_STATE state = PyGILState_Ensure();
PyObject* handler_args = PyTuple_Pack(1, PyLong_FromLong(signo));
PyObject_CallObject(py_handler, handler_args);
PyGILState_Release(state);
}
我正在构建一个简单的模块来包装 C 函数。这个模块的主要功能(test_wrapper
)基本上接收一个python函数并调用它:
#include <Python.h>
static PyObject* test_wrapper(PyObject* self, PyObject* args) {
PyObject* py_handler;
int args_ok = PyArg_ParseTuple(args, "O", &py_handler);
PyObject_CallObject(py_handler, NULL);
return Py_BuildValue("i", 0);
}
static PyMethodDef TestModuleMethods[] = {
{ "test", test_wrapper, METH_VARARGS, NULL },
{ NULL, NULL, 0, NULL }
};
static struct PyModuleDef TestModule = {
PyModuleDef_HEAD_INIT,
"test_module",
NULL,
-1,
TestModuleMethods
};
PyMODINIT_FUNC PyInit_test_module(void) {
return PyModule_Create(&TestModule);
}
上面的代码工作正常。问题是,假设我需要在未来以另一种方式调用传递的 python 函数 (py_handler
),例如通过信号处理程序,现在它需要一个整数作为参数:
PyObject* py_handler;
void handler(int signo) {
PyObject* handler_args = PyTuple_Pack(1, PyLong_FromLong(signo));
PyObject_CallObject(py_handler, handler_args); //seg fault
}
static PyObject* test_wrapper(PyObject* self, PyObject* args) {
int args_ok = PyArg_ParseTuple(args, "O", &py_handler);
//Py_INCREF(py_handler); //adding this didn't work
//calls sigaction to set handler function
return Py_BuildValue("i", 0);
}
通过这样做,PyObject_CallObject 在被 handler
调用时崩溃(段错误)。
我可能在这里遗漏了什么?
如果相关,我正在用 setup.py
构建 .so
。
获取并释放GIL足以解决问题:
void handler(int signo) {
PyGILState_STATE state = PyGILState_Ensure();
PyObject* handler_args = PyTuple_Pack(1, PyLong_FromLong(signo));
PyObject_CallObject(py_handler, handler_args);
PyGILState_Release(state);
}