docs.html.svn-base

来自「本人找过多个在linux下c++的lua5.1封装库,但很少.luabind已经」· SVN-BASE 代码 · 共 1,535 行 · 第 1/5 页

SVN-BASE
1,535
字号
possible to register attributes with read-only access:</p><pre class="literal-block">module(L)[    class_&lt;A&gt;(&quot;A&quot;)        .def_readonly(&quot;a&quot;, &amp;A::a)];</pre><p>When binding members that are a non-primitive type, the auto generated getterfunction will return a reference to it. This is to allow chained .-operators.For example, when having a struct containing another struct. Like this:</p><pre class="literal-block">struct A { int m; };struct B { A a; };</pre><p>When binding <tt class="docutils literal"><span class="pre">B</span></tt> to lua, the following expression code should work:</p><pre class="literal-block">b = B()b.a.m = 1assert(b.a.m == 1)</pre><p>This requires the first lookup (on <tt class="docutils literal"><span class="pre">a</span></tt>) to return a reference to <tt class="docutils literal"><span class="pre">A</span></tt>, andnot a copy. In that case, luabind will automatically use the dependency policyto make the return value dependent on the object in which it is stored. So, ifthe returned reference lives longer than all references to the object (b inthis case) it will keep the object alive, to avoid being a dangling pointer.</p><p>You can also register getter and setter functions and make them look as if theywere a public data member. Consider the following class:</p><pre class="literal-block">class A{public:    void set_a(int x) { a = x; }    int get_a() const { return a; }private:    int a;};</pre><p>It can be registered as if it had a public data member a like this:</p><pre class="literal-block">class_&lt;A&gt;(&quot;A&quot;)    .property(&quot;a&quot;, &amp;A::get_a, &amp;A::set_a)</pre><p>This way the <tt class="docutils literal"><span class="pre">get_a()</span></tt> and <tt class="docutils literal"><span class="pre">set_a()</span></tt> functions will be called instead ofjust writing  to the data member. If you want to make it read only you can justomit the last parameter. Please note that the get function <strong>has to beconst</strong>, otherwise it won't compile. This seems to be a common source of errors.</p></div><div class="section"><h2><a id="enums" name="enums">8.3&nbsp;&nbsp;&nbsp;Enums</a></h2><p>If your class contains enumerated constants (enums), you can register them aswell to make them available in Lua. Note that they will not be type safe, allenums are integers in Lua, and all functions that takes an enum, will acceptany integer. You register them like this:</p><pre class="literal-block">module(L)[    class_&lt;A&gt;(&quot;A&quot;)        .enum_(&quot;constants&quot;)        [            value(&quot;my_enum&quot;, 4),            value(&quot;my_2nd_enum&quot;, 7),            value(&quot;another_enum&quot;, 6)        ]];</pre><p>In Lua they are accessed like any data member, except that they are read-onlyand reached on the class itself rather than on an instance of the class.</p><pre class="literal-block">Lua 5.0  Copyright (C) 1994-2003 Tecgraf, PUC-Rio&gt; print(A.my_enum)4&gt; print(A.another_enum)6</pre></div><div class="section"><h2><a id="operators" name="operators">8.4&nbsp;&nbsp;&nbsp;Operators</a></h2><p>To bind operators you have to include <tt class="docutils literal"><span class="pre">&lt;luabind/operator.hpp&gt;</span></tt>.</p><p>The mechanism for registering operators on your class is pretty simple. You usea global name <tt class="docutils literal"><span class="pre">luabind::self</span></tt> to refer to the class itself and then you justwrite the operator expression inside the <tt class="docutils literal"><span class="pre">def()</span></tt> call. This class:</p><pre class="literal-block">struct vec{    vec operator+(int s);};</pre><p>Is registered like this:</p><pre class="literal-block">module(L)[    class_&lt;vec&gt;(&quot;vec&quot;)        .def(<strong>self + int()</strong>)];</pre><p>This will work regardless if your plus operator is defined inside your class oras a free function.</p><p>If your operator is const (or, when defined as a free function, takes a constreference to the class itself) you have to use <tt class="docutils literal"><span class="pre">const_self</span></tt> instead of<tt class="docutils literal"><span class="pre">self</span></tt>. Like this:</p><pre class="literal-block">module(L)[    class_&lt;vec&gt;(&quot;vec&quot;)        .def(<strong>const_self</strong> + int())];</pre><p>The operators supported are those available in Lua:</p><pre class="literal-block">+    -    *    /    ==    &lt;    &lt;=</pre><p>This means, no in-place operators. The equality operator (<tt class="docutils literal"><span class="pre">==</span></tt>) has a littlehitch; it will not be called if the references are equal. This means that the<tt class="docutils literal"><span class="pre">==</span></tt> operator has to do pretty much what's it's expected to do.</p><p>Lua does not support operators such as <tt class="docutils literal"><span class="pre">!=</span></tt>, <tt class="docutils literal"><span class="pre">&gt;</span></tt> or <tt class="docutils literal"><span class="pre">&gt;=</span></tt>. That's why youcan only register the operators listed above. When you invoke one of thementioned operators, lua will define it in terms of one of the avaliableoperators.</p><p>In the above example the other operand type is instantiated by writing<tt class="docutils literal"><span class="pre">int()</span></tt>. If the operand type is a complex type that cannot easily beinstantiated you can wrap the type in a class called <tt class="docutils literal"><span class="pre">other&lt;&gt;</span></tt>. For example:</p><p>To register this class, we don't want to instantiate a string just to registerthe operator.</p><pre class="literal-block">struct vec{    vec operator+(std::string);};</pre><p>Instead we use the <tt class="docutils literal"><span class="pre">other&lt;&gt;</span></tt> wrapper like this:</p><pre class="literal-block">module(L)[    class_&lt;vec&gt;(&quot;vec&quot;)        .def(self + <strong>other&lt;std::string&gt;()</strong>)];</pre><p>To register an application (function call-) operator:</p><pre class="literal-block">module(L)[    class_&lt;vec&gt;(&quot;vec&quot;)        .def( <strong>self(int())</strong> )];</pre><p>There's one special operator. In Lua it's called <tt class="docutils literal"><span class="pre">__tostring</span></tt>, it's notreally an operator. It is used for converting objects to strings in a standardway in Lua. If you register this functionality, you will be able to use the luastandard function <tt class="docutils literal"><span class="pre">tostring()</span></tt> for converting your object to a string.</p><p>To implement this operator in C++ you should supply an <tt class="docutils literal"><span class="pre">operator&lt;&lt;</span></tt> forstd::ostream. Like this example:</p><pre class="literal-block">class number {};std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, number&amp;);...module(L)[    class_&lt;number&gt;(&quot;number&quot;)        .def(<strong>tostring(self)</strong>)];</pre></div><div class="section"><h2><a id="nested-scopes-and-static-functions" name="nested-scopes-and-static-functions">8.5&nbsp;&nbsp;&nbsp;Nested scopes and static functions</a></h2><p>It is possible to add nested scopes to a class. This is useful when you needto wrap a nested class, or a static function.</p><pre class="literal-block">class_&lt;foo&gt;(&quot;foo&quot;)    .def(constructor&lt;&gt;())    <strong>.scope    [        class_&lt;inner&gt;(&quot;nested&quot;),        def(&quot;f&quot;, &amp;f)    ]</strong>;</pre><p>In this example, <tt class="docutils literal"><span class="pre">f</span></tt> will behave like a static member function of the class<tt class="docutils literal"><span class="pre">foo</span></tt>, and the class <tt class="docutils literal"><span class="pre">nested</span></tt> will behave like a nested class of <tt class="docutils literal"><span class="pre">foo</span></tt>.</p><p>It's also possible to add namespace's to classes using the same syntax.</p></div><div class="section"><h2><a id="derived-classes" name="derived-classes">8.6&nbsp;&nbsp;&nbsp;Derived classes</a></h2><p>If you want to register classes that derives from other classes, you canspecify a template parameter <tt class="docutils literal"><span class="pre">bases&lt;&gt;</span></tt> to the <tt class="docutils literal"><span class="pre">class_</span></tt> instantiation. Thefollowing hierarchy:</p><pre class="literal-block">struct A {};struct B : A {};</pre><p>Would be registered like this:</p><pre class="literal-block">module(L)[    class_&lt;A&gt;(&quot;A&quot;),    class_&lt;B, A&gt;(&quot;B&quot;)];</pre><p>If you have multiple inheritance you can specify more than one base. If B wouldalso derive from a class C, it would be registered like this:</p><pre class="literal-block">module(L)[    class_&lt;B, bases&lt;A, C&gt; &gt;(&quot;B&quot;)];</pre><p>Note that you can omit <tt class="docutils literal"><span class="pre">bases&lt;&gt;</span></tt> when using single inheritance.</p><div class="note"><p class="first admonition-title">Note</p><p class="last">If you don't specify that classes derive from each other, luabind will notbe able to implicitly cast pointers between the types.</p></div></div><div class="section"><h2><a id="smart-pointers" name="smart-pointers">8.7&nbsp;&nbsp;&nbsp;Smart pointers</a></h2><p>When you register a class you can tell luabind that all instances of that classshould be held by some kind of smart pointer (boost::shared_ptr for instance).You do this by giving the holder type as an extra template parameter tothe <tt class="docutils literal"><span class="pre">class_</span></tt> you are constructing, like this:</p><pre class="literal-block">module(L)[    class_&lt;A, boost::shared_ptr&lt;A&gt; &gt;(&quot;A&quot;)];</pre><p>You also have to supply two functions for your smart pointer. One that returnsthe type of const version of the smart pointer type (boost::shared_ptr&lt;const A&gt;in this case). And one function that extracts the raw pointer from the smartpointer. The first function is needed because luabind has to allow thenon-const -&gt; conversion when passing values from Lua to C++. The secondfunction is needed when Lua calls member functions on held types, the thispointer must be a raw pointer, it is also needed to allow the smart_pointer -&gt;raw_pointer conversion from Lua to C++. They look like this:</p><pre class="literal-block">namespace luabind {    template&lt;class T&gt;    T* get_pointer(boost::shared_ptr&lt;T&gt;&amp; p)    {        return p.get();    }    template&lt;class A&gt;    boost::shared_ptr&lt;const A&gt;*    get_const_holder(boost::shared_ptr&lt;A&gt;*)    {        return 0;    }}</pre><p>The second function will only be used to get a compile time mappingof <tt class="docutils literal"><span class="pre">boost::shared_ptr&lt;A&gt;</span></tt> to its const version,<tt class="docutils literal"><span class="pre">boost::shared_ptr&lt;const</span> <span class="pre">A&gt;</span></tt>. It will never be called, so thereturn value doesn't matter (only the return type).</p><p>The conversion that works are (given that B is a base class of A):</p><div class="topic"><p class="topic-title first">From Lua to C++</p><table border="1" class="docutils"><colgroup><col width="51%" /><col width="49%" /></colgroup><thead valign="bottom"><tr><th class="head">Source</th><th class="head">Target</th></tr></thead><tbody valign="top"><tr><td><tt class="docutils literal"><span class="pre">holder_type&lt;A&gt;</span></tt></td><td><tt class="docutils literal"><span class="pre">A*</span></tt></td></tr><tr><td><tt class="docutils literal"><span class="pre">holder_type&lt;A&gt;</span></tt></td><td><tt class="docutils literal"><span class="pre">B*</span></tt></td></tr><tr><td><tt class="docutils literal"><span class="pre">holder_type&lt;A&gt;</span></tt></td><td><tt class="docutils literal"><span class="pre">A</span> <span class="pre">const*</span></tt></td></tr><tr><td><tt class="docutils literal"><span class="pre">holder_type&lt;A&gt;</span></tt></td><td><tt class="docutils literal"><span class="pre">B</span> <span class="pre">const*</span></tt></td></tr><tr><td><tt class="docutils literal"><span class="pre">holder_type&lt;A&gt;</span></tt></td><td><tt class="docutils literal"><span class="pre">holder_type&lt;A&gt;</span></tt></td></tr><tr><td><tt class="docutils literal"><span class="pre">holder_type&lt;A&gt;</span></tt></td><td><tt class="docutils literal"><span class="pre">holder_type&lt;A</span> <span class="pre">const&gt;</span></tt></td></tr><tr><td><tt class="docutils literal"><span class="pre">holder_type&lt;A</span> <span class="pre">const&gt;</span></tt></td><td><tt class="docutils literal"><span class="pre">A</span> <span class="pre">const*</span></tt></td></tr><tr><td><tt class="docutils literal"><span class="pre">holder_type&lt;A</span> <span class="pre">const&gt;</span></tt></td><td><tt class="docutils literal"><span class="pre">B</span> <span class="pre">const*</span></tt></td></tr><tr><td><tt class="docutils literal"><span class="pre">holder_type&lt;A</span> <span class="pre">const&gt;</span></tt></td><td><tt class="docutils literal"><span class="pre">holder_type&lt;A</span> <span class="pre">const&gt;</span></tt></td></tr></tbody></table></div><div class="topic"><p class="topic-title first">From C++ to Lua</p><table border="1" class="docutils"><colgroup><col width="56%" /><col width="44%" /></colgroup>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?