1 回答
TA贡献1847条经验 获得超11个赞
报错的原因是这样的:Python扩展函数必须有一定的C原型:
PyObject *func(PyObject *self, PyObject *args)
方法槽包含类型的函数指针
PyObject *(*)(Pyobject *, PyObject *)
旧的方法是将函数强制转换为此指针类型以存储到方法槽中。显式强制转换将void (*)()消除 to的转换错误PyObject *(*)(Pyobject *, PyObject *)。转换有效,但需要显式转换。如果不存在显式强制转换,则 C 编译器必须发出诊断消息。
您的代码没有显式转换,因此您必须收到警告
{"gen_nums", gen_nums, METH_VARARGS, "This is a threading test"},
在任何情况下,如果有一个显式的 cast,该程序仍然是一个正确的程序,直到 Python 尝试调用您的函数gen_nums(),因为 Python 会这样做,就好像它的原型是
PyObject *gen_nums(PyObject *, PyObject *);
现在C 标准说,虽然到目前为止一切都很好,但从现在开始程序的行为是未定义的,因为C11 6.3.2.3:
指向一种类型函数的指针可以转换为指向另一种类型函数的指针,然后再返回;结果应与原始指针相等。如果使用转换后的指针调用类型与引用类型不兼容的函数,则行为未定义。
你的函数返回void,即什么都没有,但你问“为什么它NULL只有Sleep()在那里才返回。原因是“未定义的行为”。
至于如何解决这个问题,请阅读并理解第 1 章(共 1 章)。用 C 或 C++ 扩展 Python - 那里有很多细节,但修复这个简单函数所需的一切都在那里详细说明。如果您遇到问题,请不要继续提问但参考文档中的问题。
该函数的修复方法是将其写为
static PyObject *gen_nums(PyObject *self, PyObject *args) {
int i;
for(i = 0; i < 10; i++) {
printf("Printed from C thread...\n");
Sleep(1000);
}
Py_RETURN_NONE;
}
添加回答
举报