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;
}
添加回答
舉報
