2016-08-25 7 views
9

मैं इस से पहले कहा गया है पता है, लेकिन मैं असफल डेल्फी के लिए कुछ सी ++ संरचनाओं/यूनियनों कन्वर्ट करने के लिए Hikvision एसडीके उपयोग करने के लिए कोशिश कर रहा हूँ करने के लिए एक सी ++ संघ कन्वर्ट करने के लिए।कैसे डेल्फी

सी ++ संरचनाओं/यूनियनों मैं कन्वर्ट करने के लिए कोशिश कर रहा हूँ निम्न हैं:

PNetItcSingleTriggerCfg = ^TNetItcSingleTriggerCfg; 
    TNetItcSingleTriggerCfg = record 
    byEnable:  Byte; 
    byRes1:  array [0..2] of Byte; 
    dwTriggerType: DWord; 
    uTriggerParam: TNetItcTriggerParamUnion; 
    byRes:   array [0..63] of Byte; 
    end; 

    PNetItcTriggerParamUnion = ^TNetItcTriggerParamUnion; 
    TNetItcTriggerParamUnion = record 
    case integer of 
     0: (uLen:    array [0..1069] of DWord); 
     1: (struIOSpeed:  TNetItcPostIOSpeedParam); 
     2: (struSingleIO:  TNetItcPostSingleIOParam); 
     3: (struPostRs485: TNetItcPostRS485Param); 
     4: (struPostRadar: TNetItcPostRS485RadarParam); 
     5: (struVtCoil:  TNetItcPostVTCoilParam); 
     6: (struHvt:   TNetItcPostHvtParam); 
     7: (struIOTL:   TNetItcEPoliceIOTLParam); 
     8: (struEpoliceRs485: TNetItcEPoliceRS485Param); 
     9: (struPERs485:  TNetItcEPoliceRS485Param);   
     10:(struPostMpr:  TNetItcPostMprParam); 
     11:(struViaVtCoil: TNetDvrViaVtCoilParam); 
     12:(struPostImt:  TNetItcPostImtParam); 
     13:(struPostPrs:  TNetItcPostPrsParam); 
     14:(struIpcHvt:  TNetIpcPostHvtParam); 
     15:(struHvtV50:  TNetIpcPostHvtParamV50); 
    end; 

और मैं भी एक नेस्टेड रिकॉर्ड के रूप में यह होने की कोशिश की है:

struct{ 
    BYTE       byEnable; 
    BYTE       byRes1[3]; 
    DWORD       dwTriggerType; 
    NET_ITC_TRIGGER_PARAM_UNION uTriggerParam; 
    BYTE       byRes[64]; 
}NET_ITC_SINGLE_TRIGGERCFG,*LPNET_ITC_SINGLE_TRIGGERCFG; 

union{ 
    DWORD        uLen[1070]; 
    NET_ITC_POST_IOSPEED_PARAM   struIOSpeed; 
    NET_ITC_POST_SINGLEIO_PARAM  struSingleIO; 
    NET_ITC_POST_RS485_PARAM   struPostRs485; 
    NET_ITC_POST_RS485_RADAR_PARAM  struPostRadar; 
    NET_ITC_POST_VTCOIL_PARAM   struVtCoil; 
    NET_ITC_EPOLICE_IOTL_PARAM   struIOTL; 
    NET_ITC_EPOLICE_RS485_PARAM  struEpoliceRs485; 
    NET_ITC_EPOLICE_RS485_PARAM  struPERs485; 
}NET_ITC_TRIGGER_PARAM_UNION,*LPNET_ITC_TRIGGER_PARAM_UNION; 

मैं निम्नलिखित की कोशिश की है (के रूप में यहाँ http://rvelthuis.de/articles/articles-convert.html#unions सुझाव)

PNetItcSingleTriggerCfg = ^TNetItcSingleTriggerCfg; 
    TNetItcSingleTriggerCfg = record 
    byEnable:  Byte; 
    byRes1:  array [0..2] of Byte; 
    dwTriggerType: DWord; 
    uTriggerParam: record 
     case integer of 
     0: (uLen:    array [0..1069] of DWord); 
     1: (struIOSpeed:  TNetItcPostIOSpeedParam); 
     2: (struSingleIO:  TNetItcPostSingleIOParam); 
     3: (struPostRs485: TNetItcPostRS485Param); 
     4: (struPostRadar: TNetItcPostRS485RadarParam); 
     5: (struVtCoil:  TNetItcPostVTCoilParam); 
     6: (struHvt:   TNetItcPostHvtParam); 
     7: (struIOTL:   TNetItcSingleIOTLParam); 
     8: (struEpoliceRs485: TNetItcEPoliceRS485Param); 
     9: (struPERs485:  TNetItcEPoliceRS485Param); 
     10:(struPostMpr:  TNetItcPostMprParam); 
     11:(struViaVtCoil: TNetDvrViaVtCoilParam); 
     12:(struPostImt:  TNetItcPostImtParam); 
     13:(struPostPrs:  TNetItcPostPrsParam); 
     14:(struIpcHvt:  TNetIpcPostHvtParam); 
     15:(struHvtV50:  TNetIpcPostHvtParamV50); 
     end; 
    byRes:   array [0..63] of Byte; 
    end; 

मैं यहाँ पर इसी तरह के सवाल को देखा है (अर्थात। How do I translate a C union into Delphi?), लेकिन मेरे उदाहरण में संघ संरचना के बीच में है, और जैसा कि मैं समझता हूं कि केस स्टेटमेंट का 'अंत' रिकॉर्ड भी समाप्त होता है।

मुझे लगता है कि मैं केस स्टेटमेंट में फ़ील्ड के लिए एक ही स्मृति आवंटन वाले एक संस्करण रिकॉर्ड के पीछे सिद्धांत को समझता हूं, इसलिए खेतों में इस्तेमाल किया जाएगा या तो, या जो मैं काम नहीं कर सकता वह यह बताना है कि कैसे डीएलएल इन अभिलेखों तक पहुंच रहा है, भले ही यह struName.unionName.fieldName या struName.fieldName और यूनियन को कैसे परिभाषित किया गया है (यानी केस स्टेटमेंट का चयनकर्ता क्या है, और कैसे पता चले कि चयनकर्ता किस डेटा प्रकार है)।

मैं अनुवाद करने के लिए तीन समान संरचना है, और आंकड़ा अगर मैं एक दरार कर सकते हैं, मैं उन सभी दरार कर सकते हैं।

रिकॉर्ड के रूप में ऊपर वर्णित है, मुझे त्रुटि संदेश 'पैरामीटर त्रुटि मिलती रहती है साथ

। एसडीके एपीआई में इनपुट या आउटपुट पैरामीटर डीएलएल से एक फंक्शन कॉल करते समय न्यूल है (यदि आपको इस पर अधिक जानकारी चाहिए, तो कृपया पूछें), जो मुझे लगता है कि मेरे रिकॉर्ड सही तरीके से परिवर्तित नहीं हुए हैं।

मैं HCNetSDK.dll SDK संस्करण 5.0.3.20 उपयोग कर रहा हूँ और मेरे आईडीई XE7 यह है कि अगर मदद करता है।

किसी भी मदद की सराहना की जाएगी।

+2

एफडब्ल्यूआईडब्ल्यू, रिकॉर्ड और यूनियनों को यहां परिवर्तित करने पर अधिक: http://rvelthuis.de/articles/articles-convert.html#unions लेकिन जैसा कि @ डेविड हेफरनन ने पहले ही कहा है, आपका रूपांतरण ठीक है, लेकिन संरेखण बंद हो सकता है। उस आलेख में संरेखण के बारे में एक अनुभाग भी है। –

+0

यह वास्तव में एक डुप्ली है। https://stackoverflow.com/search?q=%5Bdelphi%5D+union –

+0

वास्तव में एक डुप्ली नहीं है। पूछने वाले ने अच्छा शोध किया है और जानना चाहता है कि परिणामस्वरूप कोड अपेक्षित व्यवहार क्यों नहीं करता है। –

उत्तर

6

कि संरचना संरेखण सेटिंग्स मान लिया जाये तो मेल खाते हैं अपने प्रयास संघ कन्वर्ट करने के लिए दोनों सही हैं। आप जो भी चाहें उसका उपयोग कर सकते हैं। इसके लायक होने के लिए, मैं पहला दृष्टिकोण पसंद करूंगा जहां आप संघ का प्रतिनिधित्व करने के लिए एक प्रकार घोषित करते हैं।

जो कुछ भी अपने वास्तविक समस्या है, यह संघ रूपांतरण के साथ झूठ प्रतीत नहीं होता है। इसका परीक्षण करने का एक आसान तरीका यह जांचना है कि प्रकारों का आकार सी ++ और डेल्फी संस्करणों में मेल खाता है, और प्रत्येक सदस्य के ऑफसेट से मेल खाता है।

डेल्फी में सी ++ और SizeOf में sizeof के प्रकार का परीक्षण करने के लिए परीक्षण करें। ऑफसेट्स के लिए offsetof मैक्रो सी ++ के लिए मैक्रो और डेल्फी के लिए my answer here में दिखाया गया चाल का उपयोग करें।

+0

दरअसल, इसके बारे में सोचना: एक संघ का उचित रूपांतरण शायद पैक किए गए रिकॉर्ड का उपयोग करना चाहिए। AFAIK, सी मानक यह अनिवार्य बनाता है कि सभी तत्व एक ही पते पर गठबंधन किए गए हैं, लेकिन कोई डेल्फी मानक नहीं है और मुझे नहीं पता कि यह वर्तमान में उपयोग में आने वाले सभी कंपाइलरों के लिए सच है या नहीं। पैक किए गए रिकॉर्ड सुनिश्चित करते हैं कि सभी भागों को गठबंधन किया गया है वही पता –

+2

@RudyVelthuis हमने इस चर्चा को कई बार पहले किया था। पैक किए गए रिकॉर्ड को गठबंधन करने के लिए मजबूर करता है। इसका लेआउट पर कोई प्रभाव नहीं पड़ेगा क्योंकि एक संस्करण रिकॉर्ड हमेशा एक ही ऑफसेट पर संस्करण सदस्यों को रखता है। लेकिन यह संरचना के गलत संरेखण का कारण बन जाएगा। उदाहरण के लिए एक इंट और डबल युक्त एक यूनियन आकार 8 है, और संरेखण 8. जब गठबंधन किया जाता है तो इसे हमेशा 8 बाइट सीमाओं पर रखा जाना चाहिए। यदि आप इसे पैक करते हैं तो ऐसा नहीं होगा। यदि सी ++ कोड संघ को संरेखण 1 के लिए मजबूर करता है, तो इसे पैक करें, अन्यथा नहीं। –

+0

@ डेविड मेरे प्रश्न का उत्तर देने के लिए समय देने के लिए धन्यवाद। कम से कम अब मैं यह देखने के लिए कहीं और देख सकता हूं कि मेरी त्रुटि कहां है। तो संघ के चयनकर्ता को क्या परिभाषित करता है? –