2010-05-09 6 views
6

मेरे पास एक सी ++ प्रोजेक्ट है जो सी बाइसन पार्सर का उपयोग करता है। सी पार्सर समारोह संकेत के एक struct कार्यों कि उचित एएसटी नोड्स बनाने कॉल करने के लिए उपयोग करता है जब प्रस्तुतियों जंगली भैंसों के द्वारा कम कर रहे हैं: परियोजना के सी ++ भाग में,सी कॉलबैक फ़ंक्शंस एक अनाम नामस्थान में परिभाषित किया गया है?

typedef void Node; 
struct Actions { 
    Node *(*newIntLit)(int val); 
    Node *(*newAsgnExpr)(Node *left, Node *right); 
    /* ... */ 
}; 

अब, मैं उन संकेत भरने

class AstNode { 
    /* ... */ 
}; 
class IntLit : public AstNode { 
    /* ... */ 
}; 

extern "C" { 
    Node *newIntLit(int val) { 
    return (Node*)new IntLit(val); 
    } 

    /* ... */ 
} 

Actions createActions() { 
    Actions a; 
    a.newIntLit = &newIntLit; 
    /* ... */ 
    return a; 
} 

अब मुझे extern "C" के भीतर रखने का एकमात्र कारण यह है क्योंकि मैं चाहता हूं कि उन्हें सी कॉलिंग सम्मेलन हों। लेकिन सबसे अच्छा, मैं चाहता हूं कि उनके नाम अभी भी उलझ जाएंगे। उन्हें सी कोड से कभी भी नाम नहीं कहा जाता है, इसलिए नाम मैंगलिंग एक मुद्दा नहीं है। उन्हें उलझाने से नाम विवादों से बचेंगी, क्योंकि कुछ कार्यों को error कहा जाता है, और सी ++ कॉलबैक फ़ंक्शन में अन्य मॉड्यूल के साथ नाम संघर्ष से बचने के लिए निम्नलिखित की तरह बदसूरत नाम हैं।

extern "C" { 
    void uglyNameError(char const *str) { 
    /* ... */ 
    } 

    /* ... */ 
} 

a.error = &uglyNameError; 

मैंने सोचा कि क्या यह महज समारोह प्रकार सी लिंकेज

extern "C" void fty(char const *str); 
namespace { 
    fty error; /* Declared! But i can i define it with that type!? */ 
} 

कोई भी विचार देकर संभव हो सकता है? मैं मानक-सी ++ समाधान की तलाश में हूं।

+0

क्या आप बीसन आउटपुट को सी ++ कोड के रूप में संकलित नहीं कर सकते हैं, इस प्रकार समस्या को पूरी तरह से टाल सकते हैं? –

+0

@ कोनराड मेरे सहयोगी ने कहा कि बाइसन सी ++ मोड के साथ काम करने के लिए अच्छा नहीं है, और इसलिए हम शुद्ध सी के साथ उस हिस्से को करते हैं और इसे सारणित करते हैं, इसलिए स्कैनर के साथ एक शुद्ध सी लाइब्रेरी बनाता है। –

उत्तर

3

मुझे समस्या नहीं है। बाहरी कीवर्ड कॉलिंग सम्मेलन को प्रभावित नहीं करता है, केवल लिंकर को प्रस्तुत किया गया नाम। सी ++ में लिखा गया एक फ़ंक्शन जो एक उदाहरण विधि नहीं है, अभी भी बाहरी "सी" के साथ या बिना __cdecl है। इसके अलावा, जब तक आप एक ही स्रोत कोड फ़ाइल में createActions() बनाते हैं, तब तक इन कार्यों को बाहरी लिंकेज की आवश्यकता नहीं होती है। टकराव से बचने के लिए आप उन्हें स्थैतिक घोषित कर सकते हैं या उन्हें एक अनाम नामस्थान में डाल सकते हैं।

+2

आह, मैं फिर 'स्थिर' बना सकता था। अच्छा विचार, मैंने इसके बारे में क्यों नहीं सोचा :) मैंने केवल नामित नामस्थानों के बारे में सोचा, लेकिन यह उनके संबंध में कुछ भी नहीं करेगा और 'बाहरी "सी कार्यों के लिए संघर्ष को रोक नहीं पाएगा। लेकिन वास्तव में 'स्थिर' काम कर सकता है! आपके उत्तर के शेष हिस्सों के लिए: यदि कार्यान्वयन ऐसा करना चाहता है तो यह सम्मेलन को कॉल करने में एक अंतर डाल सकता है। मैं किसी विशेष कार्यान्वयन पर निर्भर नहीं होना चाहता था, इसलिए मैंने उन्हें 'बाहरी' सी ''बनाया। –

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