docs.html.svn-base
来自「本人找过多个在linux下c++的lua5.1封装库,但很少.luabind已经」· SVN-BASE 代码 · 共 1,535 行 · 第 1/5 页
SVN-BASE
1,535 行
<pre class="literal-block">module(L, "my_library")[ // declarations namespace_("detail") [ // library-private declarations ]];</pre><p>As you might have figured out, the following declarations are equivalent:</p><pre class="literal-block">module(L)[ namespace_("my_library") [ // declarations ]];</pre><pre class="literal-block">module(L, "my_library")[ // declarations];</pre><p>Each declaration must be separated by a comma, like this:</p><pre class="literal-block">module(L)[ def("f", &f), def("g", &g), class_<A>("A") .def(constructor<int, int>), def("h", &h)];</pre><p>More about the actual declarations in the <a class="reference" href="#binding-functions-to-lua">Binding functions to Lua</a> and<a class="reference" href="#binding-classes-to-lua">Binding classes to Lua</a> sections.</p><p>A word of caution, if you are in really bad need for performance, putting yourfunctions in tables will increase the lookup time.</p></div><div class="section"><h1><a id="binding-functions-to-lua" name="binding-functions-to-lua">7 Binding functions to Lua</a></h1><p>To bind functions to Lua you use the function <tt class="docutils literal"><span class="pre">luabind::def()</span></tt>. It has thefollowing synopsis:</p><pre class="literal-block">template<class F, class policies>void def(const char* name, F f, const Policies&);</pre><ul class="simple"><li>name is the name the function will have within Lua.</li><li>F is the function pointer you want to register.</li><li>The Policies parameter is used to describe how parameters and return valuesare treated by the function, this is an optional parameter. More on this inthe <a class="reference" href="#policies">policies</a> section.</li></ul><p>An example usage could be if you want to register the function <tt class="docutils literal"><span class="pre">float</span><span class="pre">std::sin(float)</span></tt>:</p><pre class="literal-block">module(L)[ def("sin", &std::sin)];</pre><div class="section"><h2><a id="overloaded-functions" name="overloaded-functions">7.1 Overloaded functions</a></h2><p>If you have more than one function with the same name, and want to registerthem in Lua, you have to explicitly give the signature. This is to let C++ knowwhich function you refer to. For example, if you have two functions, <tt class="docutils literal"><span class="pre">int</span><span class="pre">f(const</span> <span class="pre">char*)</span></tt> and <tt class="docutils literal"><span class="pre">void</span> <span class="pre">f(int)</span></tt>.</p><pre class="literal-block">module(L)[ def("f", (int(*)(const char*)) &f), def("f", (void(*)(int)) &f)];</pre></div><div class="section"><h2><a id="signature-matching" name="signature-matching">7.2 Signature matching</a></h2><p>luabind will generate code that checks the Lua stack to see if the values therecan match your functions' signatures. It will handle implicit typecasts betweenderived classes, and it will prefer matches with the least number of implicitcasts. In a function call, if the function is overloaded and there's nooverload that match the parameters better than the other, you have anambiguity. This will spawn a run-time error, stating that the function call isambiguous. A simple example of this is to register one function that takes anint and one that takes a float. Since Lua doesn't distinguish between floats andintegers, both will always match.</p><p>Since all overloads are tested, it will always find the best match (not thefirst match). This also means that it can handle situations where the onlydifference in the signature is that one member function is const and the otherisn't.</p><div class="sidebar"><p class="first sidebar-title">Ownership transfer</p><p class="last">To correctly handle ownership transfer, create_a() would need an adoptreturn value policy. More on this in the <a class="reference" href="#policies">Policies</a> section.</p></div><p>For example, if the following function and class is registered:</p><pre class="literal-block">struct A{ void f(); void f() const;};const A* create_a();struct B: A {};struct C: B {};void g(A*);void g(B*);</pre><p>And the following Lua code is executed:</p><pre class="literal-block">a1 = create_a()a1:f() -- the const version is calleda2 = A()a2:f() -- the non-const version is calleda = A()b = B()c = C()g(a) -- calls g(A*)g(b) -- calls g(B*)g(c) -- calls g(B*)</pre></div><div class="section"><h2><a id="calling-lua-functions" name="calling-lua-functions">7.3 Calling Lua functions</a></h2><p>To call a Lua function, you can either use <tt class="docutils literal"><span class="pre">call_function()</span></tt> oran <tt class="docutils literal"><span class="pre">object</span></tt>.</p><pre class="literal-block">template<class Ret>Ret call_function(lua_State* L, const char* name, ...)template<class Ret>Ret call_function(object const& obj, ...)</pre><p>There are two overloads of the <tt class="docutils literal"><span class="pre">call_function</span></tt> function, one that callsa function given its name, and one that takes an object that should be a Luavalue that can be called as a function.</p><p>The overload that takes a name can only call global Lua functions. The ...represents a variable number of parameters that are sent to the Luafunction. This function call may throw <tt class="docutils literal"><span class="pre">luabind::error</span></tt> if the functioncall fails.</p><p>The return value isn't actually Ret (the template parameter), but a proxyobject that will do the function call. This enables you to give policies to thecall. You do this with the operator[]. You give the policies within thebrackets, like this:</p><pre class="literal-block">int ret = call_function<int>( L , "a_lua_function" , new complex_class())[ adopt(_1) ];</pre><p>If you want to pass a parameter as a reference, you have to wrap it with the<a class="reference" href="http://www.boost.org/doc/html/ref.html">Boost.Ref</a>.</p><p>Like this:</p><pre class="literal-block">int ret = call_function(L, "fun", boost::ref(val));</pre><p>If you want to use a custom error handler for the function call, see<tt class="docutils literal"><span class="pre">set_pcall_callback</span></tt> under <a class="reference" href="#pcall-errorfunc">pcall errorfunc</a>.</p></div><div class="section"><h2><a id="using-lua-threads" name="using-lua-threads">7.4 Using Lua threads</a></h2><p>To start a Lua thread, you have to call <tt class="docutils literal"><span class="pre">lua_resume()</span></tt>, this means that youcannot use the previous function <tt class="docutils literal"><span class="pre">call_function()</span></tt> to start a thread. You haveto use</p><pre class="literal-block">template<class Ret>Ret resume_function(lua_State* L, const char* name, ...)template<class Ret>Ret resume_function(object const& obj, ...)</pre><p>and</p><pre class="literal-block">template<class Ret>Ret resume(lua_State* L, ...)</pre><p>The first time you start the thread, you have to give it a function to execute. i.e. youhave to use <tt class="docutils literal"><span class="pre">resume_function</span></tt>, when the Lua function yields, it will return the firstvalue passed in to <tt class="docutils literal"><span class="pre">lua_yield()</span></tt>. When you want to continue the execution, you just call<tt class="docutils literal"><span class="pre">resume()</span></tt> on your <tt class="docutils literal"><span class="pre">lua_State</span></tt>, since it's already executing a function, you don't passit one. The parameters to <tt class="docutils literal"><span class="pre">resume()</span></tt> will be returned by <tt class="docutils literal"><span class="pre">yield()</span></tt> on the Lua side.</p><p>For yielding C++-functions (without the support of passing data back and forth between theLua side and the c++ side), you can use the <a class="reference" href="#yield">yield</a> policy.</p><p>With the overload of <tt class="docutils literal"><span class="pre">resume_function</span></tt> that takes an <a class="reference" href="#object">object</a>, it is important that theobject was constructed with the thread as its <tt class="docutils literal"><span class="pre">lua_State*</span></tt>. Like this:</p><pre class="literal-block">lua_State* thread = lua_newthread(L);object fun = get_global(<strong>thread</strong>)["my_thread_fun"];resume_function(fun);</pre></div></div><div class="section"><h1><a id="binding-classes-to-lua" name="binding-classes-to-lua">8 Binding classes to Lua</a></h1><p>To register classes you use a class called <tt class="docutils literal"><span class="pre">class_</span></tt>. Its name is supposed toresemble the C++ keyword, to make it look more intuitive. It has an overloadedmember function <tt class="docutils literal"><span class="pre">def()</span></tt> that is used to register member functions, operators,constructors, enums and properties on the class. It will return itsthis-pointer, to let you register more members directly.</p><p>Let's start with a simple example. Consider the following C++ class:</p><pre class="literal-block">class testclass{public: testclass(const std::string& s): m_string(s) {} void print_string() { std::cout << m_string << "\n"; }private: std::string m_string;};</pre><p>To register it with a Lua environment, write as follows (assuming you are usingnamespace luabind):</p><pre class="literal-block">module(L)[ class_<testclass>("testclass") .def(constructor<const std::string&>()) .def("print_string", &testclass::print_string)];</pre><p>This will register the class with the name testclass and constructor that takesa string as argument and one member function with the name <tt class="docutils literal"><span class="pre">print_string</span></tt>.</p><pre class="literal-block">Lua 5.0 Copyright (C) 1994-2003 Tecgraf, PUC-Rio> a = testclass('a string')> a:print_string()a string</pre><p>It is also possible to register free functions as member functions. Therequirement on the function is that it takes a pointer, const pointer,reference or const reference to the class type as the first parameter. The restof the parameters are the ones that are visible in Lua, while the objectpointer is given as the first parameter. If we have the following C++ code:</p><pre class="literal-block">struct A{ int a;};int plus(A* o, int v) { return o->a + v; }</pre><p>You can register <tt class="docutils literal"><span class="pre">plus()</span></tt> as if it was a member function of A like this:</p><pre class="literal-block">class_<A>("A") .def("plus", &plus)</pre><p><tt class="docutils literal"><span class="pre">plus()</span></tt> can now be called as a member function on A with one parameter, int.If the object pointer parameter is const, the function will act as if it was aconst member function (it can be called on const objects).</p><div class="section"><h2><a id="overloaded-member-functions" name="overloaded-member-functions">8.1 Overloaded member functions</a></h2><p>When binding more than one overloads of a member function, or just bindingone overload of an overloaded member function, you have to disambiguatethe member function pointer you pass to <tt class="docutils literal"><span class="pre">def</span></tt>. To do this, you can use anordinary C-style cast, to cast it to the right overload. To do this, you haveto know how to express member function types in C++, here's a short tutorial(for more info, refer to your favourite book on C++).</p><p>The syntax for member function pointer follows:</p><pre class="literal-block"><em>return-value</em> (<em>class-name</em>::*)(<em>arg1-type</em>, <em>arg2-type</em>, <em>...</em>)</pre><p>Here's an example illlustrating this:</p><pre class="literal-block">struct A{ void f(int); void f(int, int);};</pre><pre class="literal-block">class_<A>() .def("f", (void(A::*)(int))&A::f)</pre><p>This selects the first overload of the function <tt class="docutils literal"><span class="pre">f</span></tt> to bind. The secondoverload is not bound.</p></div><div class="section"><h2><a id="properties" name="properties">8.2 Properties</a></h2><p>To register a global data member with a class is easily done. Consider thefollowing class:</p><pre class="literal-block">struct A{ int a;};</pre><p>This class is registered like this:</p><pre class="literal-block">module(L)[ class_<A>("A") .def_readwrite("a", &A::a)];</pre><p>This gives read and write access to the member variable <tt class="docutils literal"><span class="pre">A::a</span></tt>. It is also
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?