2011-12-09 24 views
6

मैं पाइथन में एक स्क्रिप्ट बनाने की कोशिश कर रहा हूं जो समांतर बंदरगाह के माध्यम से डेटा भेजता है। मैं सी भाषा में अपना खुद का मॉड्यूल बना रहा हूं।पायथन सी एक्सटेंशन मॉड्यूल में वापसी मूल्य के बिना विधि

समस्या यह है: जब मैं अपने मॉड्यूल को निष्पादित करने का प्रयास करता हूं, पायथन क्रैश होता है। कोई त्रुटि नहीं, कोई डेटा नहीं, कुछ भी नहीं। यह बस बंद हो जाता है।

#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

मैंने सी में अपना पाइथन मॉड्यूल नहीं बनाया है, लेकिन आपके फ़ंक्शन पैरालेलो में जहां इसे PyObject * वापस करना है, तो आप अंत में 1 क्यों लौट रहे हैं? – lloydm

+0

यह वास्तव में कुछ भी वापस नहीं करना चाहिए, लेकिन मैंने याद रखने के लिए उस वापसी को छोड़ दिया है यदि मैंने कभी भी एक और मॉड्यूल फिर से किया है – markmb

+0

तो अगर आप इसके बजाय न्यूल वापस करते हैं तो कैसे? 1 की बजाय जो एक अवैध सूचक है। – lloydm

उत्तर

10

पाइथन/सी एपीआई में वापस लौटने से संकेत मिलता है कि एक त्रुटि हुई है।

SystemError: error return without exception set

आप कोई भी वापस जाने के लिए कोशिश कर रहे हैं, का उपयोग करें:: लेकिन जब से तुम वास्तव में एक अपवाद सेट नहीं किया आप त्रुटि मिलती है

return Py_BuildValue(""); 
+0

मैंने अन्य टिप्पणी का उपयोग किया है: Py_None लौटाएं, और यह – markmb

+1

@markmb काम करता है, सावधान! यदि आप वापसी Py_None का उपयोग करते हैं, तो आपको संदर्भ गणना बढ़ाने की आवश्यकता है या अन्यथा आप परेशानी में भाग लेंगे। आपको या तो मेरे पास जो कुछ है, या Py_RETURN_NONE का उपयोग करना चाहिए कि दूसरे उत्तर में Py_IncRef (Py_None) है या कॉल करें –

13

सभी अजगर कार्यों एक PyObject लौटना चाहिए, जब तक कि जब वे , एक अपवाद को बढ़ाने के लिए चाहते हैं के रूप में बताया गया है: यहाँ http://docs.python.org/extending/extending.html#intermezzo-errors-and-exceptions

आप SystemError: error return without exception set प्राप्त त्रुटि संदेश, आपको बताने के लिए अपने कार्य लौटे कि शून्य (= त्रुटि, एक अपवाद बढ़ा) कोशिश कर रहा है लेकिन अजगर दुभाषिया क्या आप अपवाद को सूचित नहीं किया था चाहते हैं बढ़ाने के लिए एड।

आप एक अजगर समारोह से एक मूल्य के वापस जाने के लिए नहीं करना चाहते हैं जब आप इसे कोई भी वापसी (जो एक ही बात होता है कि अगर अजगर कोड में आप एक समारोह है कि अंत करने के लिए चलाता है या किसी के बिना एक सरल वापसी करता है बनाने के मूल्य)।

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 करने के लिए एक अजगर मॉड्यूल है/outb पहले से ही कहता है : http://pypi.python.org/pypi/portio