2016-08-15 6 views
5

std::path::Path को देखते हुए, इसे शून्य से समाप्त std::os::raw::c_char पर परिवर्तित करने का सबसे सीधा तरीका क्या है? (सी कार्यों को पार करने के लिए जो पथ लेते हैं)।पथ को * * c_char में कनवर्ट करने का सबसे सीधा तरीका क्या है?

use std::ffi::CString; 
use std::os::raw::c_char; 
use std::os::raw::c_void; 

extern "C" { 
    some_c_function(path: *const c_char); 
} 

fn example_c_wrapper(path: std::path::Path) { 
    let path_str_c = CString::new(path.as_os_str().to_str().unwrap()).unwrap(); 

    some_c_function(path_str_c.as_ptr()); 
} 

क्या इतने सारे मध्यवर्ती कदमों से बचने का कोई तरीका है?

Path -> OsStr -> &str -> CString -> as_ptr() 
+0

यह मानना ​​सटीक नहीं है कि 'पथ' को सी स्ट्रिंग में परिवर्तित किया जा सकता है। प्लेटफार्म अलग-अलग एन्कोडिंग का उपयोग कर सकते हैं और कर सकते हैं; यही कारण है कि ये अवशेष पहले स्थान पर मौजूद हैं। आप यूनिक्स सिस्टम के लिए सीमित कर रहे हैं, तो वहाँ [ 'OsStrExt'] (https://doc.rust-lang.org/std/os/unix/ffi/trait.OsStrExt.html)। – Shepmaster

+0

भी ध्यान रखें कि आप भी एक 'स्ट्रिंग', जो UTF-8 में होना चाहिए करने के लिए परिवर्तित कर रहे हैं, हालांकि सी तार कि आवश्यकता नहीं है। – Shepmaster

उत्तर

4

यह उतना आसान नहीं है जितना दिखता है। आपके द्वारा प्रदान की जाने वाली जानकारी का एक टुकड़ा नहीं है: पथ को अपेक्षित करने के लिए सी फ़ंक्शन क्या एन्कोडिंग है?

लिनक्स पर, पथ बाइट्स के "बस" सरणी हैं (0 अमान्य हैं), और एप्लिकेशन आमतौर पर उन्हें डीकोड करने का प्रयास नहीं करते हैं। (हालांकि, उन्हें उन्हें एक विशेष एन्कोडिंग के साथ डीकोड करना पड़ सकता है, उदाहरण के लिए उन्हें उपयोगकर्ता को प्रदर्शित करें, इस मामले में वे आमतौर पर वर्तमान लोकेल के अनुसार उन्हें डीकोड करने का प्रयास करेंगे, जो अक्सर यूटीएफ -8 एन्कोडिंग का उपयोग करेंगे।)

विंडोज़ पर, यह अधिक जटिल है, क्योंकि एपीआई फ़ंक्शंस की विविधताएं हैं जो "एएनएसआई" कोड पृष्ठ और "यूनिकोड" (यूटीएफ -16) का उपयोग करने वाली विविधताओं का उपयोग करती हैं। इसके अतिरिक्त, विंडोज़ यूटीएफ -8 को "एएनएसआई" कोड पेज के रूप में सेट करने का समर्थन नहीं करता है। इसका मतलब है कि निश्चित रूप से गलत है, जब तक कि पुस्तकालय विशेष रूप से उम्मीद है UTF-8 और देशी एन्कोडिंग खुद के लिए पथ धर्मान्तरित यह एक UTF-8 एन्कोडेड पथ गुजर, (हालांकि यह प्रकट हो सकता है केवल ASCII वर्ण वाली स्ट्रिंग के लिए काम करने के लिए)।

(मैं अन्य प्लेटफार्मों के बारे में पता नहीं है, लेकिन यह पहले से ही काफी गंदा है।)

जंग में, Path सिर्फ OsStr के लिए एक आवरण है। OsStr एक प्लेटफॉर्म-निर्भर प्रतिनिधित्व का उपयोग करता है जो यूटीएफ -8 के साथ संगत होने पर होता है जब स्ट्रिंग वास्तव में मान्य यूटीएफ -8 है, लेकिन गैर-यूटीएफ -8 तार एक अनिर्दिष्ट एन्कोडिंग का उपयोग करते हैं (विंडोज़ पर, यह वास्तव में WTF-8 का उपयोग कर रहा है, लेकिन यह नहीं है संविदात्मक; लिनक्स पर, यह केवल बाइट्स की सरणी है)।

इससे पहले कि आप सी फ़ंक्शन के लिए पथ पारित करें, आपको यह निर्धारित करना होगा कि स्ट्रिंग में यह कितना एन्कोडिंग हो रहा है, और यदि यह जंग के एन्कोडिंग से मेल नहीं खाता है, तो आपको इसे CString में लपेटने से पहले इसे परिवर्तित करना होगा । जंग आपको एक प्लेटफार्म-स्वतंत्र तरीके से str के अलावा किसी अन्य चीज़ पर Path या OsStr परिवर्तित करने की अनुमति नहीं देता है। यूनिक्स-आधारित लक्ष्यों पर, OsStrExt विशेषता उपलब्ध है और बाइट्स के टुकड़े के रूप में OsStr तक पहुंच प्रदान करती है।

जंग OsStr पर एक to_cstring विधि प्रदान करने के लिए इस्तेमाल किया है, लेकिन यह स्थिर कभी नहीं था, और यह, जंग 1.6.0 में पदावनत किया गया था के रूप में यह महसूस किया गया कि व्यवहार विंडोज के लिए अनुचित था (यह एक UTF-8 एन्कोडेड पथ लौटे , लेकिन विंडोज एपीआई इसका समर्थन नहीं करते हैं!)।

+2

लोकेल लिनक्स पर व्यवस्थित अनुमान होगा, लेकिन यह वास्तव में पथ एन्कोडिंग से संबंधित नहीं है। पथ 0 को छोड़कर मनमाने ढंग से बाइट्स हो सकते हैं। – bluss

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

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