Method with no return value in python extension module c

I am trying to create a script in python that sends data through a parallel port. I create my own module in C language.

The problem is that when trying to execute my module python crashes. No errors, no data, nothing. It just closes.

This is my module:

#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); } 

(It works without any python mess) I will compile it through distutils, and then, in the terminal (using xubuntu), I will put:

 import paralelo while True: paralelo.paralelo(255) 

And here it exits python, it puts "markmb @ ..."

Thanks in advance!

+6
source share
2 answers

A return of NULL to the python / c API indicates that an error has occurred. But since you did not actually throw an exception, you will get an error:

SystemError: error returning without exception

If you are trying to return None, use:

 return Py_BuildValue(""); 
+10
source

All python functions should return PyObject unless they want to raise an exception as described: here http://docs.python.org/extending/extending.html#intermezzo-errors-and-exceptions

The error message you get SystemError: error return without exception set , is trying to tell you that your function returned NULL (= error, raised an exception) but did not tell the python interpreter which exception you would like to raise.

If you do not want to return a value from a python function, you make it return None (this is the same thing that happens if you have a function in python code that runs to the end or performs a simple return without any value).

In the cpython api, you do this by returning a Py_None object and remember to increase its refcount. To help you remember about failure, there is a macro for this: http://docs.python.org/c-api/none.html#Py_RETURN_NONE .

So, the function skeleton for a function that returns nothing (= return No), you look something like this:

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

Finally, for the record: there is another python module for making ioperm / outb calls: http://pypi.python.org/pypi/portio

+13
source

Source: https://habr.com/ru/post/903470/


All Articles