2012-02-26 20 views
11

मैं जंग कोड से mysql से कनेक्ट करने का प्रयास कर रहा हूं। मैंने इन चरणों की कोशिश की है।मैं रस्ट भाषा से सी पुस्तकालय "mysql.h" को कॉल करना चाहता हूं

    1. मैंने mysql.h का उपयोग करके सी कोड लिखा, और नीचे आदेश दिया।
    
    $ gcc -shared mysqlrust.c -o libmysqlrust.so $(mysql_config --cflags) $(mysql_config --libs) $(mysql_config --cflags) 
    $ cp libmysqlrust.so /usr/local/lib/rustc/i686-unknown-linux-gnu/lib/ 
    
    2. मैंने जंग कोड लिखा, जो libmysqlrust.so पर कॉल करता है।

लेकिन मैं सी प्रकार की संरचना "MYSQL", "MYSQL_RES", "MYSQL_ROW" का उपयोग करने का तरीका नहीं समझ सका। कृपया मुझे दिखाएं कि जंग कोड से सी प्रकार की संरचना का उपयोग कैसे करें।

+2

चलिए आपके द्वारा लिखे गए कोड को देखते हैं और सटीक त्रुटि संदेश – Mark

+1

http://doc.rust-lang.org/doc/tutorial.html#passing- संरचनाएं –

उत्तर

17

सी structs से स्वचालित रूप से जंग प्रकार परिभाषाओं को बनाने का कोई तरीका नहीं है। इन परिस्थितियों में आगे बढ़ने के कुछ तरीके हैं। MySQL API को नहीं जानते, मैं बिल्कुल नहीं कह सकता कि आपको क्या करना चाहिए, लेकिन यहां कुछ विकल्प दिए गए हैं।

1) पूरी तरह से अपारदर्शी पॉइंटर्स के रूप में उनका इलाज करें।

यह सबसे अच्छी स्थिति है, और सीपीआई पर निर्भर करता है कि वह हमेशा एक सूचक के रूप में संरचना लेता है, जिसमें अपने स्वयं के कन्स्ट्रक्टर और विनाशक कार्य होते हैं, और जो भी आपको संरचना के अंदर पहुंचने के लिए एक्सेसर फ़ंक्शंस प्रदान करता है। इन मामलों में आप केवल type MYSQL = ctypes::void को परिभाषित करते हैं और केवल इसे एक असुरक्षित सूचक *MYSQL के रूप में उपयोग करते हैं। कभी-कभी सबसे आसान तरीका अंतराल को भरने और इस परिदृश्य को संभव बनाने के लिए अपने स्वयं के सी रैपर लिखना है।

शेष परिदृश्यों में सी संरचना के समान संरचना के साथ एक जंग डेटा संरचना को फिर से परिभाषित करना शामिल है। जंग अपने डेटा संरचनाओं को सी के साथ संगत करने की कोशिश करता है जो सी के साथ संगत है (हालांकि अभी तक सफल नहीं होता है), इसलिए अक्सर सी स्ट्रक्चर के आकार, संरेखण और लेआउट के साथ जंग रिकॉर्ड या enum बनाना संभव है। देखभाल के बारे में। आप यह सुनिश्चित करना चाहते हैं कि आप core::ctypes में प्रकारों का उपयोग करें, क्योंकि उन्हें विभिन्न सामान्य प्रकारों से मेल खाने के लिए परिभाषित किया गया है।

ध्यान दें कि ctypes मॉड्यूल जल्द ही एक अधिक व्यापक libc संगतता मॉड्यूल के पक्ष में जा रहा है।

2) एक जंग के रिकॉर्ड को परिभाषित करें जो आंशिक रूप से सही है।

यदि एपीआई कन्स्ट्रक्टर और विनाशकों को प्रदान करता है, लेकिन आपको अभी भी संरचना के कुछ क्षेत्रों तक पहुंच की आवश्यकता है, तो आप सही आकार और संरेखण जैसी चीजों को अनदेखा करते हुए, जिन क्षेत्रों की आप परवाह करते हैं, उन्हें पाने के लिए पर्याप्त संरचना को परिभाषित कर सकते हैं। । जैसे type MSQL = { filler1: ctypes::int, ..., connector_fd: *ctypes::char }। आप जिस अंतिम क्षेत्र की देखभाल करते हैं उस पर संरचना को परिभाषित करना बंद कर सकते हैं क्योंकि आपके पास सही आकार और संरेखण के साथ ढेर पर आवंटित करने के लिए एक सी फ़ंक्शन है। जंग कोड में आप हमेशा इसे एक असुरक्षित सूचक के साथ संदर्भित करते हैं: let mysql: *MYSQL = mysqlrust::create_mysql();

3) सामग्री के बारे में देखभाल किए बिना सही आकार और संरेखण वाला एक जंग रिकॉर्ड परिभाषित करें।

यदि आपके पास कन्स्ट्रक्टर/विनाशक कार्य नहीं हैं, या ढेर पर संरचना को स्टोर करने की आवश्यकता है, लेकिन आपके पास अन्यथा संरचना की सामग्री में हेरफेर करने के लिए एक्सेसर फ़ंक्शन हैं, तो आपको सही के साथ एक जंग रिकॉर्ड को परिभाषित करने की आवश्यकता है आकार और संरेखण। ऐसा करने के लिए, बस uint (जो हमेशा पॉइंटर आकार का होता है) या uint के tuples के फ़ील्ड जोड़ें, जब तक कि दोनों के sizeof और core::sys::size_of आकार पर सहमत न हों। u8 एस के साथ पैड यदि आकार सूचक आकार का एक बहु नहीं है। संरेखण अधिकार प्राप्त करना एक और रहस्यमय प्रक्रिया है, लेकिन uint फ़ील्ड्स का उपयोग करके आप आमतौर पर उपयोग करने योग्य संरेखण के साथ समाप्त हो जाएंगे (शायद - मुझे वास्तव में यह नहीं पता कि यह कथन कितना सटीक है)।

मैं सैनिटी चेक में परीक्षण जोड़ने की सिफारिश करता हूं कि भविष्य में टूटने से बचाने के लिए जंग और सी आकार पर सहमत हैं।

3) वास्तव में पूरे सी संरचना को फिर से परिभाषित करें।

यह बड़े structs के लिए एक बहुत ही गंभीर स्थिति है, और यह सिद्धांत में संभव है, लेकिन मुझे नहीं लगता कि किसी ने इसे MYSQL जितना बड़ा संरचना के लिए किया है। यदि आप कर सकते हैं तो मैं इससे बचूंगा। आखिरकार ऐसा करने के लिए एक क्लैंग-आधारित टूल होगा।

यहाँ सी structs साथ इंटरॉप के कुछ उदाहरण हैं:

https://github.com/jdm/rust-socket/blob/master/socket.rs - यह विभिन्न सॉकेट structs को पुनर्परिभाषित, खेतों इसके बारे में परवाह नहीं है के लिए प्लेसहोल्डर जोड़ने। ध्यान दें कि यह पैडिंग के लिए u8 का उपयोग करता है, लेकिन मुझे लगता है कि uint सही संरेखण उत्पन्न करने की अधिक संभावना है।

https://github.com/erickt/rust-zmq/blob/master/zmq.rs

https://github.com/pcwalton/rust-spidermonkey - यह एक कुछ हद तक एक जटिल एपीआई के साथ इंटरॉप को दर्शाता है।

+0

मैंने इन संरचनाओं को जंग, और परिभाषित कार्यों में फिर से परिभाषित किया है। टाइप MYSQL = ctypes :: शून्य; टाइप MYSQL_RES = ctypes :: शून्य; टाइप करें MYSQL_ROW = ctypes :: शून्य; और मैं आगे बढ़ गया हूं। लेकिन एक और समस्या। मैं ** char को str के सरणी में नहीं डाल सकता। मुझे कैसे हल करना चाहिए? धन्यवाद। –

+0

आपको सी स्ट्रिंग्स की सरणी को पार करने के लिए असुरक्षित कोड का उपयोग करना होगा और उन्हें जंग के तारों के वेक्टर में परिवर्तित करना होगा। कुछ https://gist.github.com/1928234 (अनचाहे) – brson

+0

जैसा मुझे मिला। मैंने सफलतापूर्वक "str :: from_cstr" असुरक्षित कोड का उपयोग किया है। बहुत बहुत धन्यवाद। :) –

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