2011-12-09 45 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