2011-02-28 10 views
5

मुझे यह प्रश्न इस चीनी ब्लॉग http://chenyufei.info/blog/2011-02-28/wrap-c-function-closure-gcc-nested-function/ से मिलता है लेखक लेखक सी भाषा में बंद करना चाहते हैं, और उन्होंने पाया कि जीसीसी में नेस्टेड फ़ंक्शन (और बंद) की क्षमता है। उदाहरण के लिए:रैप और कॉल सी फ़ंक्शन के बारे में

typedef int (*func_t)(int arg); 


int foo(int a) { 

    return a + 1; 

} 


func_t create_wrap_function(func_t f) { 

    int wrapped(int arg) { 

     // call original function 

     int val = f(arg); 

     fprintf(log_func_call, "arg: %d ret: %d", arg, val); 

     return val; 
    } 

    return wrapped; 
} 

लेकिन यह सामान्य समाधान नहीं है। create_wrap_function ने फ़ंक्शन प्रारूप को ठीक किया है, क्योंकि func_t प्रारूप को सीमित करता है।

जैसा कि हम जानते हैं, लुआ बंद हो गया है, और सी समारोह भी कॉल कर सकता है। मैं इसे कार्यान्वित करना चाहता हूं जैसे: हम जो फ़ंक्शन कॉल करना चाहते हैं वह foo1 और foo2 है, उनके पास विभिन्न प्रकार के तर्क और वापसी मूल्य हैं। Do_Lua_Wrap में

lua_returnValue returnValue1 = Do_Lua_Wrap(__FILE__, __LINE__, foo1, 1); 
lua_returnValue returnValue2 = Do_Lua_Wrap(__FILE__, __LINE__, foo2, "string data", 1.2345); 

, यह लुआ कार्य करने के लिए foo1 और 1 पारित तो सामान्य प्रक्रिया की तरह समारोह foo1 कॉल करेगा:

int foo1(int a) { 
    ... 
    return intValue; 
} 

double foo2(char* str, double a) { 
    ... 
    return dblValue; 
} 

सी क्लाइंट में, जैसे फ़ंक्शन को कॉल करें। फिर foo2 और एक char * और Lua फ़ंक्शन के लिए एक डबल मान पास करें, फिर सामान्य प्रक्रिया की तरह foo2 फ़ंक्शन को कॉल करें। लुआ फ़ंक्शन में, यह FILE और LINE और फ़ंक्शन तर्कों के बारे में कुछ अतिरिक्त लॉग लिखने के बारे में जानकारी लॉग कर सकता है।

लेकिन मुझे इस बारे में कोई जानकारी नहीं है कि समारोह को कैसे लिखना है D_Lua_Wrap सी और लुआ में, क्या यह संभव है?

यदि संभव हो, तो क्या आप मुझे कुछ सलाह दे सकते हैं?

उत्तर

2

आप variadic function में स्पष्ट रूप से रुचि रखते हैं, लेकिन समस्या लूआ स्टैक पर धक्का देने के लिए तर्कों के प्रकार का निर्धारण कर रही है। मैं एक जोड़ी दृष्टिकोण का सुझाव देंगे:

  1. पहले एक प्रारूप स्ट्रिंग एक ला printf परिवार या बाइनरी पैकिंग प्रारूपों अक्सर उच्च स्तर भाषाओं में इस्तेमाल शामिल करने के लिए किया जाएगा। उदाहरण के लिए, lpack लुआ मॉड्यूल में उपयोग किए गए स्वरूप पैटर्न पर देखें। कुंजी पर प्रारूप स्ट्रिंग के माध्यम से स्कैन करें यह निर्धारित करें कि तर्क प्रदान किए गए हैं।

  2. वैकल्पिक रूप से, आप variant प्रकार को लागू कर सकते हैं। प्रत्येक तर्क को संरचना में लपेटने की आवश्यकता होगी। इसके अलावा, तर्कों की कुल संख्या को पहले पैरामीटर के रूप में प्रदान करने की आवश्यकता होगी।

  3. अंत में, आप के बजाय एक variadic समारोह का उपयोग करने के दो सरणियों में तर्क दे सकते हैं। पहली सरणी में दूसरी सरणी में void * पॉइंटर्स के लक्ष्य के अनुरूप समेकित प्रकार शामिल होंगे। क्लाइंट कोड को रखने के लिए इस विधि को अधिकांश घर की आवश्यकता है, लेकिन काफी साफ है।या तो एक या दोनों सरणी के अंत में सरणी की लंबाई निर्दिष्ट करने या एक सेंटीनेल मान निर्दिष्ट करने के लिए एक तर्क भी आवश्यक होगा।

उम्मीद है कि उन तरीकों में से एक आपके लिए काम करना चाहिए। निजी तौर पर, मैं पहले विकल्प के साथ जाऊंगा और lpack कोड का उपयोग गाइड के रूप में करता हूं। यह आपके प्रश्न में निर्दिष्ट फ़ंक्शन हस्ताक्षर के सबसे नज़दीक आता है।

+0

आपका उत्तर बहुत अच्छा है! – sagasw

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