2011-12-09 85 views
6

我試圖在通過並行端口發送數據的python中創建一個腳本。我正在用C語言創建我自己的模塊。python c擴展模塊中沒有返回值的方法

問題是:當我嘗試執行我的模塊時,python崩潰。沒有錯誤,沒有數據,什麼都沒有。它只是關閉。

這是我的模塊:

#include <Python.h> 
#include <sys/io.h> 
#define BaseAddr 0x378 

/*---------------------------------------------------------------------------------- 
Este es un módulo destinado a controlar el puerto paralelo. 
Probablemente tenga que ser ejecutado como administrador. 

Created by markmb 
------------------------------------------------------------------------------------*/ 

static PyObject * 
paralelo(PyObject *self, PyObject *args){ 
    int pin; 
    ioperm(BaseAddr,3,1); 
    if (!PyArg_ParseTuple(args, "i", &pin)) 
     return NULL; 
    outb(pin,BaseAddr); 
    ioperm(BaseAddr,3,0); 
    return 1 
} 
PyMethodDef methods[] = { 
    {"paralelo", paralelo, METH_VARARGS, "Sends data through a parallel port"}, 
    {NULL, NULL, 0, NULL} 
}; 
PyMODINIT_FUNC 
initparalelo(void){ 
    (void) Py_InitModule("paralelo", methods); 
} 

(它的工作原理沒有所有蟒蛇一塌糊塗) 我編譯通過的distutils,然後在終端(使用Xubuntu上),我把:

import paralelo 
while True: 
    paralelo.paralelo(255) 

在這裏,它走出蟒蛇,它把「markmb @ ...」

在此先感謝!

+0

我還沒有在C中創建自己的Python模塊,但是在函數paralelo中,它應該返回PyObject *,爲什麼你在最後返回1? – lloydm

+0

它真的不應該不會返回任何東西,但是如果我再次執行另一個模塊,我留下了回憶。 – markmb

+0

那麼如果您返回NULL,那麼該怎麼辦?而不是1,這是一個無效的指針。 – lloydm

回答

10

將NULL返回到python/c API指示發生了錯誤。但因爲你實際上並沒有設置一個例外,你得到的錯誤:

SystemError: error return without exception set

如果你試圖返回無,用途:

return Py_BuildValue(""); 
+0

我使用了其他評論說的:return Py_None,它的工作原理 – markmb

+1

@markmb,小心!如果使用返回Py_None,則需要增加引用計數,否則會遇到麻煩。你應該使用我所擁有的,或者Py_RETURN_NONE那個其他的答案,或者調用Py_IncRef(Py_None) –

13

所有的Python函數應返回的PyObject,除非當他們解釋如下:http://docs.python.org/extending/extending.html#intermezzo-errors-and-exceptions

你得到的錯誤信息SystemError: error return without exception set,試圖告訴你你的函數返回NULL(=錯誤,引發異常),但沒有通知python解釋器你有什麼異常想編輯提出。

當你不想從一個python函數返回一個值時,你會讓它返回None(如果你在python代碼中有一個運行到最後的函數或者沒有任何簡單的返回值)。

在cpython api中,你可以通過返回Py_None對象來做到這一點,並且不要忘記增加它的refcount。爲了幫助您不忘記引用次數,有一個宏可以幫助您:http://docs.python.org/c-api/none.html#Py_RETURN_NONE

因此,在函數骨架的函數返回什麼(=返回無)你是這個樣子:

static PyObject * 
myfunction(PyObject *self, PyObject *args){ 
    if (!PyArg_ParseTuple(args, "i", ...)) 
     return NULL; 
    /* .... */ 
    Py_RETURN_NONE; 
} 

最後,備案:有做的ioperm一個Python模塊/ OUTB調用已:http://pypi.python.org/pypi/portio