2014-11-03 17 views
5

में यूनियन संरचना को हल करें मुझे सी-यूनियन संरचना XEvent को हल करने में समस्या है।जंग FFI

मैं जंग में एक्सलिब और एक्स रिकॉर्ड एक्सटेंशन के साथ प्रयोग कर रहा हूं। मैं rust-bindgen के साथ एफएफआई-बाइंडिंग उत्पन्न कर रहा हूं। सभी कोड github alxkolm/rust-xlib-record पर होस्ट किए गए हैं।

लाइन src/main.rs:106 पर समस्या होती है जब मैं XEvent संरचना से डेटा निकालने का प्रयास करता हूं।

 

let key_event: *mut xlib::XKeyEvent = event.xkey(); 
println!("KeyPress {}", (*key_event).keycode); // this always print 128 on any key 

मेरा प्रोग्राम महत्वपूर्ण घटनाओं को सुनता है और keycode प्रिंट करता है। लेकिन यह किसी भी कुंजी पर हमेशा 128 होता है। मुझे लगता है कि सी यूनियन प्रकार से जंग प्रकार के लिए यह गलत रूपांतरण है।

XEvent की परिभाषा src/xlib.rs:1143 से शुरू होती है। यह सी-यूनियन है। मूल सी परिभाषा here

गिटहब से कोड cargo run कमांड द्वारा चलाया जा सकता है। यह त्रुटियों के बिना संकलित है।

मैं क्या गलत करता हूं?

+0

क्या आप वास्तव में त्रुटि का सामना कर सकते हैं? यदि आपके पास संकलन-समय त्रुटि है, तो संकलक त्रुटि संदेश उपयोगी होगा; यदि आपके पास लोड समय त्रुटि है, तो ... या वह समस्या है जिसे आप हमेशा '128' प्राप्त करते हैं और कुछ और उम्मीद कर रहे थे? –

+0

किसी भी कुंजी पर मैं हमेशा कुंजीकोड दबाता हूं 128. यह त्रुटियों के बिना पूरी तरह से संकलित है। प्रश्न का पाठ ठीक करें। – alxkolm

+1

क्या आपने जांच की है कि ईवेंट का प्रकार आप किस चीज की अपेक्षा करेंगे? जेनरेटेड जंग कोड आपको अंधेरे से पालन करता है: आप 'xkey' के लिए पूछते हैं, यह स्मृति को संगत रूप से व्याख्या करता है, हालांकि अगर यह एक महत्वपूर्ण दबाया गया ईवेंट नहीं था लेकिन कुछ और नहीं, तो यह समझ में नहीं आता है। –

उत्तर

3

सावधान रहें कि rustbindgen सी union पर बाध्यकारी उत्पन्न करता है जिसमें सी में जितनी अधिक सुरक्षा होती है; परिणामस्वरूप, कॉल करने जैसा:

event.xkey(); // gets the C union 'xkey' field 

कोई क्रम जाँच लें कि xkey क्षेत्र वर्तमान में एक मूल्य युक्त होता है।

ऐसा इसलिए है क्योंकि सी ने union (यानी union टैग नहीं किया है) यह जानने के लिए कि कौन सा क्षेत्र वर्तमान में उपयोग में है), डेवलपर्स इस जानकारी (*) को एन्कोड करने के विभिन्न तरीकों से आए हैं, जो मुझे पता है:

  • बाहरी सप्लायर; आम तौर पर ठीक पहले union
  • union

यहाँ में संरचनाओं में से प्रत्येक के पहले क्षेत्र, आप बाद के मामले int type; में हैं संरचना का एक और क्षेत्र संघ के पहले क्षेत्र और प्रत्येक आंतरिक संरचना होती है इसे इंगित करने के लिए int _type; से शुरू होता है। नतीजतन, आप एक दो चरणों दृष्टिकोण की जरूरत है:

  1. जा रहा है प्रकार के मान से परामर्श type()
  2. मूल्य के आधार पर, फोन सही पुनर्व्याख्या

मानचित्रण वास्तविक क्षेत्र के लिए उम्मीद है कि सी लाइब्रेरी के प्रलेखन का हिस्सा होना चाहिए, उम्मीद है।

मैं आपको निम्न निम्न स्तर union के आसपास एक रैपर के साथ आने के लिए आमंत्रित करता हूं जो परिणाम को पुनर्प्राप्त करने के लिए सुरक्षित बना देगा। कम से कम, आप जांच सकते हैं कि यह एक्सेसर में सही प्रकार है; एक दृष्टिकोण enum के साथ आने का पूरा दृष्टिकोण है जो सभी क्षेत्रों में प्रॉक्सी लपेटता है और पैटर्न-मिलान की अनुमति देता है।

(*) और वास्तव में कभी कभी C99 में कुल मिलाकर यह उपेक्षा एक float एक int के रूप में एक union { float f; int i; } इस्तेमाल किया जा सकता पुनर्व्याख्या करने के लिए उदाहरण के लिए,।