अच्छा प्रश्न है। मुझे कुछ अस्पष्ट विचार था कि यह कितना लुभावना करता है, लेकिन मुझे पूरी तरह से और सटीक उत्तर देने के लिए पर्याप्त जानकारी नहीं थी।एक IDE और डीबगर मैं निम्नलिखित बहुत ही सरल टुकड़ा चीर-फाड़ शुरू कर दिया साथ सशस्त्र:
struct C
{
int i;
int f(int x, const char* s)
};
lua_State* L = luaL_newstate();
open(L);
module(L)
[
class_<C>("C")
.def_readwrite("index", &C::i)
.def("f", &C::f)
];
सूचना के लिए
पहली बात कि L
एक बहुत luabind को पारित कर दिया है, open
करने के लिए कॉल लुआ राज्य में कुछ वैश्विक बनाता है: __luabind_classes
टाइप उपयोगकर्ता उपयोगकर्ता और दो फ़ंक्शंस class
और property
। लुबाइंड वैश्विक चर का उपयोग नहीं कर रहा है - इसकी हर चीज को लुआ पर्यावरण में बचाया जाता है।
अब हम module(L)[...]
पर पहुंचते हैं। मूल कोड, सबसे अच्छा विवरण है पहले यहां module
है: पर्याप्त
inline module_ module(lua_State* L, char const* name = 0)
{
return module_(L, name);
}
सरल, यहाँ module_
है:
class LUABIND_API module_
{
public:
module_(lua_State* L_, char const* name);
void operator[](scope s);
private:
lua_State* m_state;
char const* m_name;
};
तो क्या हमारे छोटे से कार्यक्रम करता कॉल ऑपरेटर [] कुछ परिभाषाओं के साथ module_
वर्ग पर है (यह scope
पैरामीटर है), लेकिन module_
कक्षा जानता है जिसमें लुआ राज्य संचालित है।
struct LUABIND_API scope
{
//...
explicit scope(detail::registration* reg);
scope& operator,(scope s);
void register_(lua_State* L) const;
private:
detail::registration* m_chain;
};
scope
detail::registration
नोड्स के एक लिंक्ड सूची बनाने जा रहा है, उस सूची operator,
का उपयोग कर से आता है: scope
वर्ग भी दिलचस्प (कुछ भागों को हटा दिया जाता है और कुछ थोड़ा सरलीकृत) को देखने के लिए है। इसलिए जब एक करता है module(L) [class_<...>..., class_<...>...]
, class_
जो scope
से विरासत initializes एक detail::registration
उदाहरण के साथ उसके आधार है, तो scope
की अल्पविराम ऑपरेटर सभी पंजीकरण की कोई लिंक की गई सूची बनाता है, इस module_::operator[]
जो scope::register_
जो बारी में श्रृंखला विश्लेषण करता है और कहता है register_
कॉल करने के लिए पारित हो जाता है उन सभी detail::registration
वस्तुओं पर। lua_State
हमेशा register_
पर भेज दिया गया है।
पुhew। अब देखते हैं कि क्या होता है जब कोई class_<C>("C").def("f", &C::f)
करता है। यह में detail::registration
सदस्य में एक निश्चित नाम के साथ class_<C>
का एक उदाहरण बनाता है। class_::def
विधि कॉलिंग reg संरचना और whatnot में लिखते हैं, लेकिन यहाँ def
से कॉल श्रृंखला में एक बहुत ही दिलचस्प लाइन गहरी है:
object fn = make_function(
L, f, deduce_signature(f, (Class*)0), policies);
ओह, deduce_signature
, मैं वास्तव में है कि देखना चाहती थी। अब मैं इसे unsee करना चाहते हैं, लेकिन जिस तरह से यह काम करता है यह है: अंधेरे पूर्वप्रक्रमक टोना को बढ़ावा देने के द्वारा सहायता प्राप्त (BOOST_PP_ITERATE
और कुछ अन्य उपयोगिताओं) के माध्यम से के बाद एक और LUABIND_MAX_ARITY के बीच प्रत्येक N के लिए उत्पन्न होता है:
template <class R, class T, class A1, classA2, ..., classAN>
boost::mpl::vectorN_PLUS_2<R, T, A1, A2, ..., AN> // type of return value
deduce_signature(R(T::*)(A1, A2, ..., AN))
{
return boost::mpl::vectorN_PLUS_2<R, T, A1, A2, ..., AN>()
}
फिर से, इस तरह का एक कार्य सभी एन के लिए 1 और LUABIND_MAX_ARITY के बीच जेनरेट किया गया है जो डिफ़ॉल्ट रूप से 10 है। कॉन्स्ट विधियों, वर्चुअल रैपर और फ्री फ़ंक्शंस को संभालने के लिए कुछ ओवरलोड हैं, जिसका अर्थ है कि लगभग 50 deduce_signature
फ़ंक्शंस हैं जो आपके स्रोतों में प्रीप्रोसेसर के ठीक बाद और संकलन शुरू होने से पहले समाप्त होते हैं। वहां से, यह def
पर भेजे गए कार्यों के लिए सही deduce_signature
अधिभार चुनने के लिए संकलक का काम है और यह सही boost::mpl::vectorX
प्रकार वापस करेगा। वहां से make_function
कुछ भी कर सकता है - इसमें पैरामीटर प्रकारों की एक [संकलित समय] सूची है और कुछ और टेम्पलेट जादू के माध्यम से इन्हें गिना जाता है, लुआ मूल्यों में परिवर्तित किया जाता है और इसी तरह से।
यह वह जगह है जहां मैं रुक जाऊंगा।जांच लुबाइंड 0.8.1 पर आधारित है। अधिक उत्तरों के लिए लुबाइंड के कोड को ब्राउज़/डिबग करने के लिए स्वतंत्र महसूस करें - इसमें कुछ समय लगता है लेकिन स्टाइल में उपयोग करने के बाद यह मुश्किल नहीं है :) शुभकामनाएं।
टीएल; डीआर: जादू ... काला जादू