2014-09-30 34 views
13

में सी फ़ंक्शन पॉइंटर्स में इंटरफ़ेस बनाएं, मैंने शायद मेरे प्रश्न शीर्षक को सही तरीके से वर्णित नहीं किया हो, कृपया आवश्यकता होने पर इसे संपादित करें।जंग

मैं टोकरे को LXC library, जो सी

मैं सफलतापूर्वक lxc_get_version या lxc_container_new की तरह साधारण कार्यों कहा जाता है में लिखा है के लिए एक जंग इंटरफ़ेस कोशिश कर रहा हूँ, लेकिन मैं struct lxc_container ब्लॉक में वर्णित कार्यों के लिए उपयोग नहीं कर सकते। यहाँ

#[link(name = "lxc")] 
extern { 
    // LXC part 
    fn lxc_get_version() -> *const c_char; 
    fn lxc_container_new(name: *const c_char, configpath: *const c_char) -> LxcContainer; 

    // LXC container parts 
    fn is_defined(container: &LxcContainer) -> bool; 
} 

और एक त्रुटि है:

यहाँ मेरी कोड का एक हिस्सा है

note: test.o: In function `LxcContainer::is_defined::heb2f16a250ac7940Vba': 
test.0.rs:(.text._ZN12LxcContainer10is_defined20heb2f16a250ac7940VbaE+0x3e): undefined reference to `is_defined' 

संपादित करें: मैं कामयाब रहे कि सी structs अंदर कार्यों समारोह संकेत कहा जाता है। मैंने "जंग सी फ़ंक्शन पॉइंटर" जैसे कुछ Google को करने का प्रयास किया है, लेकिन बिना किस्मत के।

struct S { 
    void (*f)(int, long) 
} 

इसका मतलब है कि struct S एक क्षेत्र f कहा जाता है जो एक समारोह के लिए सूचक है शामिल हैं:

उत्तर

20

जब आप कुछ इस तरह (सी में) देखें। इसका मतलब यह नहीं है कि लाइब्रेरी स्वयं f नामक फ़ंक्शन का खुलासा करती है। उदाहरण के लिए, इस मान्य है:

void some_function_1(int x, long y) { ... } 

void some_function_2(int a, long b) { ... } 

int main() { 
    struct S s1; s1.f = some_function_1; 
    struct S s2; s2.f = some_function_2; 
} 

यहाँ struct उदाहरण s1some_function_1 के लिए सूचक होते हैं, और s2some_function_2 के लिए सूचक होता है।

जब आप कुछ सी पुस्तकालय के लिए जंग में एफएफआई बाध्यकारी लिख रहे हैं, तो आप आम तौर पर सी संरचनाओं के लिए जंग समकक्ष परिभाषित करते हैं। rust-bindgen जैसे कुछ टूल स्वचालित रूप से भी ऐसा कर सकते हैं।

#[repr(C)] 
struct LxcContainer { 
    name: *mut c_char, 
    configfile: *mut c_char, 
    // ... 
    numthreads: c_int, 
    // ... 
    is_defined_f: extern fn(c: *mut LxcContainer) -> bool, 
    state_f: extern fn(c: *mut LxcContainer) -> *const c_char, 
    // ... 
} 

है, अजीब दिखने सी समारोह सूचक प्रकार जंग में extern fn समारोह सूचक प्रकार के अनुरूप: अपनी मामले में आप कुछ इस तरह लिखने के लिए होगा। आप extern "C" fn(...) -> ... भी लिख सकते हैं, लेकिन "C" क्वालीफायर डिफ़ॉल्ट है इसलिए इसकी आवश्यकता नहीं है।

आप इन कार्यों कॉल करने के लिए कुछ इस तरह लिखने के लिए करना होगा:

impl LxcContainer { 
    fn is_defined_f(&mut self) -> bool { 
     unsafe { 
      (self.is_defined_f)(self as *mut LxcContainer) 
     } 
    } 
} 

तुम एक कच्चे सूचक के लिए एक संदर्भ कास्ट करने के लिए की जरूरत है और आप भी आदेश विधि कॉल को स्पष्ट करने के लिए कोष्ठक में self.is_defined_f रैप करने के लिए की जरूरत है और क्षेत्र का उपयोग।

आप जंगली here में एफएफआई पर अधिक पा सकते हैं। हालांकि, फ़ंक्शन पॉइंटर्स को संक्षेप में समझाया गया है।

+0

उत्तर के लिए धन्यवाद, अब मैं फ़ंक्शन पॉइंटर्स तक पहुंच प्राप्त कर सकता हूं। मैंने सी प्रतिनिधित्व के लिए एक संरचना और इसके चारों ओर जंग के प्रतिनिधित्व के लिए एक रैपर लिखा है। दुर्भाग्यवश मैं 'is_defined' पर कॉल नहीं कर सकता क्योंकि मैं LxcContainer संरचना को * LxcContainer के रूप में कार्य करने के लिए पास नहीं कर सकता। Dereference त्रुटि होती है। क्या आप कृपया अपने उत्तर में फ़ंक्शन पॉइंटर कॉलिंग का कुछ उदाहरण जोड़ सकते हैं? धन्यवाद। – bbrodriges

+0

@bbrodriges, देर से उत्तर के लिए खेद है, लेकिन मैंने संरचना के क्षेत्रों में संग्रहीत कार्यों को कॉल करने के उदाहरण के साथ अपना उत्तर अपडेट किया है। –