python c扩展模块中没有返回值的方法

发布于 2024-12-20 08:39:56 字数 1279 浏览 3 评论 0原文

我正在尝试用 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);
}

它可以在没有所有 python 混乱的情况下工作) 我通过 distutils 编译它,然后在终端(使用 xubuntu)中输入:

import paralelo
while True:
    paralelo.paralelo(255)

在这里,它从 python 中输出,它输入“markmb@...”

提前致谢!

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

The problem is: when I try to execute my module, python crashes. No errors, no data, nothing. It simply 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 all python mess)
I compile it through distutils and then, in terminal (using xubuntu), I put:

import paralelo
while True:
    paralelo.paralelo(255)

And here, it goes out of python, it puts "markmb@..."

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

活泼老夫 2024-12-27 08:39:56

所有 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 对象来完成此操作,并且不要忘记增加其引用计数。为了帮助您不要忘记引用计数,有一个宏可以为您完成此操作: http://docs.python .org/c-api/none.html#Py_RETURN_NONE

因此,一个不返回任何内容(=返回 None)的函数的函数骨架看起来像这样:

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

最后,郑重声明:已经有一个用于执行 ioperm/outb 调用的 python 模块: http://pypi.python.org/pypi/portio

All python functions should return a PyObject, unless when they want to raise an exception, as explained: 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, raise an exception) but did not inform the python interpreter what exception you wanted to raise.

When you don't want to return a value from a python function you make it return None (which is same thing that happens if you in python code have a function that runs to the end or does a simple return without any value).

In the cpython api you do this by returning the Py_None object, and don't forget to increment its refcount. To help you not forgetting the refcount there is a macro to do it for you: http://docs.python.org/c-api/none.html#Py_RETURN_NONE.

So a function skeleton for a function returning nothing (=returning None) 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 a python module for doing the ioperm/outb calls already: http://pypi.python.org/pypi/portio

找回味觉 2024-12-27 08:39:56

向 python/c API 返回 NULL 表示发生了错误。但由于您实际上没有设置异常,因此会出现错误:

系统错误:错误返回,未设置异常

如果您尝试返回 None,请使用:

return Py_BuildValue("");

Returning NULL to the python/c API indicates that an error has occurred. But since you didn't actually set an exception you get the error:

SystemError: error return without exception set

If you are trying to return None, use:

return Py_BuildValue("");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文