2012-11-15 14 views
5

द्वारा पारित कुछ मूल्यों को सही ढंग से वापस नहीं करता है, मैं पाइथन से डीएलएल को कॉल करने का प्रयास कर रहा हूं। डीएलएल सीधे सी में लिखा गया है और इसके बारे में बहुत जटिल नहीं है। यह ऐसी चीज है जो कि प्रकार के लिए बिल्कुल बनाई गई है। हालांकि मुझे डीएलएल फ़ंक्शन कॉल से लौटाई गई संरचना के भीतर सही मान प्राप्त करने में समस्या हो रही है। उत्तीर्ण संरचना में पहला मूल्य सही ढंग से लौटाया जाता है लेकिन अन्य नहीं होते हैं।पायथन सीटीपीएस संदर्भ

कोड स्मृति में एक बफर से एकाधिक संदेश पढ़ता है। यह एक ReadFirst()/ReadNext() कोडिंग प्रतिमान का उपयोग करता है। राज्य का ट्रैक रखने के लिए पास किया गया एक "वर्तमान संदेश" संरचना है।

यहाँ सी struct है कि मौजूदा ReadFirst()/ReadNext() राज्य रखती है ...

typedef struct 
    { 
    unsigned int   uMsgNum; 
    uint32_t    ulCurrOffset; 
    uint32_t    ulDataLen; 
    Su1553F1_ChanSpec  * psuChanSpec; 
    Su1553F1_Header  * psu1553Hdr; 
    SuCmdWordU   * psuCmdWord1; 
    SuCmdWordU   * psuCmdWord2; 
    uint16_t    * puStatWord1; 
    uint16_t    * puStatWord2; 
    uint16_t    uWordCnt; 
    uint16_t    * pauData; 
    } Su1553F1_CurrMsg; 

यहाँ ctypes struct समकक्ष ctypes में लिखा है ...

class CurrMsg_1553F1(ctypes.Structure): 
    ''' Data structure for the current 1553 message info structure ''' 
    _pack_ = 1 
    _fields_ = [("MsgNum",  ctypes.c_uint32), 
       ("CurrOffset", ctypes.c_uint32), 
       ("DataLen",  ctypes.c_uint32), 
       ("pChanSpec", ctypes.POINTER(ChanSpec_1553F1)), 
       ("p1553Hdr", ctypes.c_void_p), 
       ("pCmdWord1", ctypes.POINTER(CmdWord)), 
       ("pCmdWord2", ctypes.POINTER(CmdWord)), 
       ("pStatWord1", ctypes.c_void_p), 
       ("pStatWord2", ctypes.c_void_p), 
       ("WordCnt",  ctypes.c_uint16), 
       ("pData",  ctypes.c_void_p)] 

मैं नीचे अधिक जानकारी प्रदान करूंगा, लेकिन समस्या का क्रूक्स यह है कि ReadFirst()/ReadNext() को कॉल करने से MsgNum के लिए सही मूल्य वापस आते हैं लेकिन अन्य मान कचरा होते हैं। यहां एक नमूना उत्पादन ...

MsgNum 0 CurrOffset 40912728 DataLen 40912732 Messages = 3664897 
MsgNum 1 CurrOffset 40912728 DataLen 40912748 Messages = 60417 
MsgNum 2 CurrOffset 40912728 DataLen 40912748 Messages = 60417 
etc. 

MsgNum सही है और ReadFirst()/ReadNext() समय की सही संख्या iterates है। CurrOffset, और DataLen के मान हालांकि कचरा हैं। (संदेश मान को पॉइंटर से अन्य मेमोरी में संदर्भित किया जाता है। मुझे नहीं लगता कि मेरे पास अभी तक यह अधिकार है लेकिन मुझे इसे तब तक सहेजना होगा जब तक कि मुझे यह अन्य सामान ठीक न हो जाए। अगर CurrOffset और DataLen गलत हैं तो pChanSpec के सूचक यह भी शायद गलत है।)

यहाँ कार्यों के लिए इंटरफेस रहे हैं ...

EnI106Status enI106_Decode_First1553F1 
    (SuI106Ch10Header * psuHeader, 
    void    * pvBuff, 
    Su1553F1_CurrMsg * psuMsg); 

EnI106Status enI106_Decode_Next1553F1 
    (Su1553F1_CurrMsg * psuMsg); 

इन DLL कार्य (डिबगिंग प्रिंट बयानों के साथ) द्वारा कहा जाता हो ...

def __init__(self, PacketIO): 
    self.CurrMsg = CurrMsg_1553F1() 

def Decode_First1553F1(self): 
    Status = self.PacketIO._IrigDataDll.enI106_Decode_First1553F1(ctypes.byref(self.PacketIO.Header), ctypes.byref(self.PacketIO.Buffer), ctypes.byref(self.CurrMsg)) 
    print "MsgNum %d CurrOffset %d DataLen %d Messages = %d" % \ 
     (Decode1553.CurrMsg.MsgNum, Decode1553.CurrMsg.CurrOffset, Decode1553.CurrMsg.DataLen, Decode1553.CurrMsg.pChanSpec.contents.MsgCnt) 
    return Status 

def Decode_Next1553F1(self): 
    Status = self.PacketIO._IrigDataDll.enI106_Decode_Next1553F1(ctypes.byref(self.CurrMsg)) 
    print "MsgNum %d CurrOffset %d DataLen %d Messages = %d" % \ 
     (Decode1553.CurrMsg.MsgNum, Decode1553.CurrMsg.CurrOffset, Decode1553.CurrMsg.DataLen, Decode1553.CurrMsg.pChanSpec.contents.MsgCnt) 
    return Status 

सी डीएलएल विजुअल स्टूडियो 2005 के तहत संकलित है। मैंने इस डीएलएल का बहुत उपयोग किया है बिना किसी समस्या के विभिन्न सी और सी ++ .NET प्रोग्राम के साथ।

मैं ctypes और structs का इस्तेमाल किया है अन्य कोड में मान वापस जाने के लिए और यह सिर्फ ठीक काम करने के लिए लग रहा था हो गया है। चूंकि संरचना में पहला मान ठीक है लेकिन बाद के मान डेटा संरेखण समस्या की तरह "महसूस" से दूर हैं। मैंने ctypes संरचना में पैक = 1 सेट किया है और संकलित DLL कोड में बाइट संरेखण सेट किया है। मैंने प्रत्येक संरचना के आकार के प्रिंटआउट किए हैं और सत्यापित हैं कि वे अपेक्षित आकार हैं।

मैंने थोड़ी देर के लिए इस पर दीवार के खिलाफ अपने सिर को हराया है और विचारों से बाहर हूं। आगे क्या कोशिश करने के बारे में कोई विचार?

+0

कोड करने के लिए अजगर कोड में सक्षम होना चाहिए, आप ByRef (self.CurrMsg) पास है, लेकिन आप Decode1553.CurrMsg से खेतों मुद्रित करें। क्या आप इसके बजाय फ़ील्ड प्रिंट नहीं कर सकते हैं। CurrMsg इसके बजाय? –

उत्तर

2

मैं ध्यान दें सी struct का पहला तत्व अहस्ताक्षरित int है, लेकिन अपने अजगर संरचना c_uint32 है। आप सुनिश्चित हैं कि वे आपके वास्तुकला पर एक ही आकार के हैं?

पहले, मैं अजगर घोषणा से _pack_ को हटा दें और किसी भी #pragma pack या सी स्रोत से अन्य संरेखण जोड़तोड़ होगा:

हैं कि किसी भी मदद नहीं है, मैं समस्या के स्रोत का पता लगाने के लिए निम्न करना होगा । एक ज्ञात जगह, मूल संरेखण से शुरू करें।

फिर ...

मैं एक सी कार्यक्रम struct से अधिक पुनरावृति और offsetof(struct, field) साथ प्रत्येक सदस्य की ऑफसेट मुद्रित करने के लिए लिखना चाहते हैं। साथ ही, इस कार्यक्रम को पहले() और अगली() को कुछ हद तक कॉल करने के लिए कॉल करना चाहिए और बाइनरी में, जैसे फाइलों में, structs लिखना चाहिए।

अगला, संरचना मॉड्यूल का उपयोग करके एक पायथन लिपि लिखें और सी प्रोग्राम से लिखे गए structs पर पुनरावृत्त, और फ़ील्ड आकार और संरेखण के ज्ञान के साथ सशस्त्र, struct.unpack (...) पर कॉल करें स्वरूप स्ट्रिंग जो संरचना को सही ढंग से परिभाषित करता है।

कि ज्ञान के साथ

आप ठीक ढंग से अपने ctypes.Structure

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