2011-12-09 17 views
6

Tôi đang cố tạo một tập lệnh trong python gửi dữ liệu qua cổng song song. Tôi đang tạo mô-đun của riêng mình bằng ngôn ngữ C.Phương thức không có giá trị trả về trong mô-đun mở rộng python c

Vấn đề là: khi tôi cố gắng thực thi mô-đun của mình, sự cố python. Không có lỗi, không có dữ liệu, không có gì. Nó đơn giản đóng lại.

Đây là mô-đun của tôi:

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

(Nó hoạt động mà không cần tất cả mớ hỗn độn python) tôi biên dịch nó qua distutils và sau đó, trong thiết bị đầu cuối (sử dụng Xubuntu), tôi đặt:

import paralelo 
while True: 
    paralelo.paralelo(255) 

Và ở đây, nó đi ra khỏi python, nó đặt "markmb @ ..."

Cảm ơn trước!

+0

Tôi chưa tạo mô-đun Python của riêng mình trong C, nhưng trong hàm paralelo của bạn, nơi nó được cho là trả về PyObject *, tại sao bạn trả về 1 ở cuối? – lloydm

+0

Nó thực sự không nên trở về không có gì, nhưng tôi để lại cho nhớ nếu tôi đã bao giờ làm một mô-đun một lần nữa – markmb

+0

Vì vậy, làm thế nào về nếu bạn trở về NULL thay thế? Thay vì 1 là con trỏ không hợp lệ. – lloydm

Trả lời

10

Trả về NULL cho API python/c cho biết đã xảy ra lỗi. Nhưng kể từ khi bạn không thực sự thiết lập một ngoại lệ bạn nhận được lỗi:

SystemError: error return without exception set

Nếu bạn đang cố gắng để trở lại Không, sử dụng:

return Py_BuildValue(""); 
+0

Tôi đã sử dụng nhận xét khác nói: trả về Py_None và nó hoạt động – markmb

+1

@markmb, cẩn thận! Nếu bạn sử dụng trả lại Py_None, bạn cần tăng số lượng tham chiếu hoặc nếu không bạn sẽ gặp rắc rối. Bạn nên sử dụng những gì tôi có hoặc Py_RETURN_NONE mà câu trả lời khác có hoặc gọi Py_IncRef (Py_None) –

13

Tất cả các chức năng python nên trả về một PyObject, trừ khi họ muốn nêu một ngoại lệ, như được giải thích: tại đây http://docs.python.org/extending/extending.html#intermezzo-errors-and-exceptions

Thông báo lỗi bạn nhận được SystemError: error return without exception set, đang cố gắng cho bạn biết rằng hàm của bạn đã trả về NULL (= lỗi, tăng ngoại lệ) nhưng không thông báo cho trình thông dịch python muốn ed để nâng cao.

Khi bạn không muốn trả về giá trị từ hàm python bạn trả về giá trị Không (điều tương tự xảy ra nếu bạn trong mã python có hàm chạy đến cuối hoặc trả về đơn giản mà không cần bất kỳ giá trị).

Trong api cpython bạn làm điều này bằng cách trả về đối tượng Py_None và đừng quên tăng số lần truy cập của nó. Để giúp bạn không quên việc refcount có một vĩ mô để làm điều đó cho bạn: http://docs.python.org/c-api/none.html#Py_RETURN_NONE.

Vì vậy, một hàm khung cho một hàm trả về không có gì (= trở về None), bạn trông giống như thế này:

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

Cuối cùng, đối với các bản ghi: có một mô-đun python cho làm ioperm/OUTB gọi đã : http://pypi.python.org/pypi/portio