2009-08-04 14 views
8

मैंने सी में ड्राइवर के लिए एक डीएलएल विकसित किया है। मैंने सी ++ में एक परीक्षण कार्यक्रम लिखा और डीएलएल ठीक काम करता है।पायथन सीटीपी रिकर्सिव संरचनाएं

अब मैं पाइथन का उपयोग करके इस डीएलएल के साथ बातचीत करना चाहता हूं। मैंने अधिकांश उपयोगकर्ता परिभाषित सी संरचनाओं को सफलतापूर्वक छुपाया है, लेकिन एक बिंदु है जहां मुझे सी संरचनाओं का उपयोग करना है। मैं अजगर के लिए नया हूं इसलिए मुझे चीजें गलत हो सकती हैं।

मेरा दृष्टिकोण सीटीपी का उपयोग करके अजगर में कुछ संरचनाओं को फिर से परिभाषित करना है, फिर चर को मेरे डीएलएल में पास करना है। हालांकि इन वर्ग में मैं एक कस्टम लिंक्ड सूची जो, का पालन के रूप में

class EthercatDatagram(Structure): 
    _fields_ = [("header", EthercatDatagramHeader), 
       ("packet_data_length", c_int), 
       ("packet_data", c_char_p), 
       ("work_count", c_ushort), 
       ("next_command", EthercatDatagram)] 

यह विफल रहता है पुनरावर्ती प्रकार होते हैं क्योंकि अंदर EthercatDatagram, EthercatDatagram पहले से ही निर्धारित नहीं है तो पार्सर एक त्रुटि देता है।

मुझे इस लिखित सूची को पायथन में कैसे प्रस्तुत करना चाहिए ताकि मेरा डीएलएल इसे सही ढंग से समझ सके?

उत्तर

15

आप लगभग निश्चित रूप से एक सूचक के रूप में घोषित करना चाहते हैं। एक संरचना जिसमें खुद को शामिल करना संभव नहीं है (किसी भी भाषा में)।

मैं इस बारे में सोच रहा है कि आप क्या चाहते:

class EthercatDatagram(Structure): 
    pass 
EthercatDatagram._fields_ = [ 
    ("header", EthercatDatagramHeader), 
    ("packet_data_length", c_int), 
    ("packet_data", c_char_p), 
    ("work_count", c_ushort), 
    ("next_command", POINTER(EthercatDatagram))] 
+1

"संभव नहीं है (किसी भी भाषा में)" - यह सी/सी ++/जावा-स्टाइल structs या कक्षाओं के बारे में सच है, लेकिन बीजगणितीय डेटा प्रकार वाली भाषाओं में यह संभव नहीं है बल्कि यह भी बहुत आम है। जैसे 'डेटा सूची एक = विपक्ष एक (सूची ए) | एमएल-पारिवारिक भाषाओं में नील '(ओकमल/हैकसेल/एसएमएल/आदि)। – sinelaw

-1

आपको इसे बनाने के बाद _fields_ स्थाई रूप से पहुंचना होगा।

class EthercatDatagram(Structure) 
    _fields_ = [...] 

EthercatDatagram._fields_.append(("next_command", EthercatDatagram)) 
+1

यह काम नहीं करता है। यह संकलित करता है और चलता है, लेकिन वास्तव में कक्षा के एक उदाहरण का उपयोग करने की कोशिश करने से एक त्रुटि मिलती है: विशेषता त्रुटि: 'EthercatDatagram' ऑब्जेक्ट में कोई विशेषता नहीं है 'next_command' – user9876

+0

सही उत्तर नीचे दिया गया है, जैसा कि उपयोगकर्ता 9876 द्वारा पोस्ट किया गया है, आपको पहले कक्षा घोषित करनी होगी 'पास' के साथ, फिर फ़ील्ड को दूसरी कॉल में घोषित करें। आगे की घोषणा के रूप में इसके बारे में सोचें। – bpescatore

0

कारण है कि

EthercatDatagram._fields_.append(("next_command", EthercatDatagram)) 

काम नहीं करता है कि मशीनरी कि वर्णनकर्ता वस्तुओं बनाता है (PyCStructType_setattro समारोह का स्रोत देखें) next_command विशेषता को एक्सेस करने के लिए केवल पर कक्षा के _fields_ विशेषता के लिए सक्रिय किया गया है। सूची में नए फ़ील्ड को जोड़ना पूरी तरह से अनजान हो जाता है।

इस pitfall से बचने के लिए, _fields_ विशेषता के मान के रूप में हमेशा एक tuple (और एक सूची नहीं) का उपयोग करें: इससे यह स्पष्ट हो जाएगा कि आपको विशेषता के लिए एक नया मान असाइन करना होगा और इसे जगह में संशोधित नहीं करना होगा।

संबंधित मुद्दे