• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

               C++ 技術(shù)中心

               :: 首頁 :: 聯(lián)系 ::  :: 管理
              160 Posts :: 0 Stories :: 87 Comments :: 0 Trackbacks

            公告

            鄭重聲明:本BLOG所發(fā)表的原創(chuàng)文章,作者保留一切權(quán)利。必須經(jīng)過作者本人同意后方可轉(zhuǎn)載,并注名作者(天空)和出處(CppBlog.com)。作者Email:coder@luckcoder.com

            留言簿(27)

            搜索

            •  

            最新隨筆

            最新評論

            評論排行榜

            lua_newtable

            void lua_newtable (lua_State *L);

            創(chuàng)建一個空 table ,并將之壓入堆棧。 它等價于 lua_createtable(L, 0, 0) 。

             

            lua_gettop

            int lua_gettop (lua_State *L);

            返回棧頂元素的索引。 因為索引是從 1 開始編號的, 所以這個結(jié)果等于堆棧上的元素個數(shù)(因此返回 0 表示堆棧為空)。

             

            luaL_newmetatable

            int luaL_newmetatable (lua_State *L, const char *tname);

            如果注冊表中已經(jīng)有Key為tname的數(shù)據(jù)則返回0. 否則創(chuàng)建一個新表作為userdata的metatable,并在注冊表中注冊它然后返回1. 不過兩種情況都會把注冊表中tname相關(guān)的值壓入堆棧。

            luaL_checkudata

            void *luaL_checkudata (lua_State *L, int narg, const char *tname);

            Checks whether the function argument narg is a userdata of the type tname (see luaL_newmetatable).

            lua_pushstring

            void lua_pushstring (lua_State *L, const char *s);

            把指針 s 指向的以零結(jié)尾的字符串壓棧。 Lua 對這個字符串做一次內(nèi)存拷貝(或是復(fù)用一個拷貝), 因此 s 處的內(nèi)存在函數(shù)返回后,可以釋放掉或是重用于其它用途。 字符串中不能包含有零字符;第一個碰到的零字符會認為是字符串的結(jié)束。

             

            lua_pushlstring

            void lua_pushlstring (lua_State *L, const char *s, size_t len);

            把指針 s 指向的長度為 len 的字符串壓棧。 Lua 對這個字符串做一次內(nèi)存拷貝(或是復(fù)用一個拷貝), 因此 s 處的內(nèi)存在函數(shù)返回后,可以釋放掉或是重用于其它用途。 字符串內(nèi)可以保存有零字符。

             

            lua_pushvalue

            void lua_pushvalue (lua_State *L, int index);

            把堆棧上給定有效處索引處的元素作一個拷貝壓棧。

             

            lua_settable

            void lua_settable (lua_State *L, int index);

            作一個等價于 t[k] = v 的操作, 這里 t 是一個給定有效索引 index 處的值, v 指棧頂?shù)闹担?而 k 是棧頂之下的那個值。

            這個函數(shù)會把鍵和值都從堆棧中彈出。 和在 Lua 中一樣,這個函數(shù)可能觸發(fā) "newindex" 事件的元方法 (參見 §2.8)。

                                                                                                                                                                                                                                                                                  

            lua_pushcfunction

            void lua_pushcfunction (lua_State *L, lua_CFunction f);

            將一個 C 函數(shù)壓入堆棧。 這個函數(shù)接收一個 C 函數(shù)指針,并將一個類型為 function 的 Lua 值 壓入堆棧。當這個棧定的值被調(diào)用時,將觸發(fā)對應(yīng)的 C 函數(shù)。

            注冊到 Lua 中的任何函數(shù)都必須遵循正確的協(xié)議來接收參數(shù)和返回值 (參見 lua_CFunction)。

            lua_pushcfunction 是作為一個宏定義出現(xiàn)的:

                  #define lua_pushcfunction(L,f) lua_pushcclosure(L,f,0)

             

             

            lua_setmetatable

            int lua_setmetatable (lua_State *L, int index);

            把一個 table 彈出堆棧,并將其設(shè)為給定索引處的值的 metatable 。

             

            lua_pushcclosure

            void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);

            把一個新的 C closure 壓入堆棧。

            當創(chuàng)建了一個 C 函數(shù)后,你可以給它關(guān)聯(lián)一些值,這樣就是在創(chuàng)建一個 C closure (參見 §3.4); 接下來無論函數(shù)何時被調(diào)用,這些值都可以被這個函數(shù)訪問到。 為了將一些值關(guān)聯(lián)到一個 C 函數(shù)上, 首先這些值需要先被壓入堆棧(如果有多個值,第一個先壓)。 接下來調(diào)用 lua_pushcclosure 來創(chuàng)建出 closure 并把這個 C 函數(shù)壓到堆棧上。 參數(shù) n 告之函數(shù)有多少個值需要關(guān)聯(lián)到函數(shù)上。 lua_pushcclosure 也會把這些值從棧上彈出。

             

            lua_newuserdata

            void *lua_newuserdata (lua_State *L, size_t size);

            這個函數(shù)分配分配一塊指定大小的內(nèi)存塊, 把內(nèi)存塊地址作為一個完整的 userdata 壓入堆棧,并返回這個地址。

            userdata 代表 Lua 中的 C 值。 完整的 userdata 代表一塊內(nèi)存。 它是一個對象(就像 table 那樣的對象): 你必須創(chuàng)建它,它有著自己的元表,而且它在被回收時,可以被監(jiān)測到。 一個完整的 userdata 只和它自己相等(在等于的原生作用下)。

            當 Lua 通過 gc 元方法回收一個完整的 userdata 時, Lua 調(diào)用這個元方法并把 userdata 標記為已終止。 等到這個 userdata 再次被收集的時候,Lua 會釋放掉相關(guān)的內(nèi)存。

             

            lua_touserdata

            void *lua_touserdata (lua_State *L, int index);

            如果給定索引處的值是一個完整的 userdata ,函數(shù)返回內(nèi)存塊的地址。 如果值是一個 light userdata ,那么就返回它表示的指針。 否則,返回 NULL 

             

             

            Lua調(diào)用C++類要點:

            1.       為此類建立一個全局表,表名為類名tbClass;

            lua_newtable(L);

            int methods = lua_gettop(L);

            lua_pushstring(LT::className);

            lua_pushvalue(Lmethods);

            lua_settable(LLUA_GLOBALSINDEX);

             

             

            2.注冊一個key為T::className的metatable,并制定其中的一些成員,用于之后生成的userdata。

            // 這個表用于userdata(T的對象)的metatable

                      luaL_newmetatable(LT::className);

                      int metatable = lua_gettop(L);

                     // metatable["__index"] = tbClass

                     lua_pushliteral(L"__index");

                     lua_pushvalue(Lmethods);

                     lua_settable(Lmetatable);

            // metatable["__tostring"] = tostring_T

                     lua_pushliteral(L"__tostring");

                     lua_pushcfunction(Ltostring_T);

                     lua_settable(Lmetatable);

                 // metatable["__gc"] = gc_T

                     lua_pushliteral(L"__gc");

                     lua_pushcfunction(Lgc_T);

                     lua_settable(Lmetatable);

             

             

             

            3. 為此表指定成員,每個成員的key為類的成員函數(shù)名,Value為一個帶有閉包的統(tǒng)一函數(shù)。比如tbClass[FunName] = thunk,之后可以根據(jù)閉包得到具體是調(diào)用到哪個函數(shù)。閉包中有函數(shù)名和相應(yīng)函數(shù)的組合結(jié)構(gòu)(以lightuserdata的形式賦給閉包)。這些類成員函數(shù)參數(shù)都必須包括lua_State,因為它需要的參數(shù)都會在lua堆棧中。

            // 為tbClass填充成員函數(shù)

                     for (RegType *l = T::methodsl->namel++)

                     {

                          /* edited by Snaily: shouldn't it be const RegType *l ... ? */

                          lua_pushstring(Ll->name);

            // 把(函數(shù)名,函數(shù)地址)pair以lightuserdata的形式作為C closure的upvalue入棧

                          lua_pushlightuserdata(L, (void*)l);

            // 把一個新的C closure 壓入堆棧。為upvalue的個數(shù),并指定回調(diào)函數(shù)統(tǒng)一為thunk    lua_pushcclosure(Lthunk, 1);         

            // tbClass[FunName] = Function

            lua_settable(Lmethods);

                     }

             

            4.創(chuàng)建C對象給腳本使用b = Account.new(Account, 30); new是tbClass下的一個函數(shù)(另外指定的,不會掉到thunk,這一句會調(diào)用到C的一個函數(shù),里面會生成一個C對象,然后創(chuàng)建一個userdata 用于關(guān)聯(lián)到這個新生成的C對象。最后為這個userdata綁定上我們上面注冊為T::classname的metatable。因為定制了metatable的__index成員,所以當userdata找不到的成員會去調(diào)用__index,因為之前我們把__index綁定到tbClass,所以也會調(diào)用到tbClass的相應(yīng)成員。

             

                 // 創(chuàng)建一個新的T對象,并創(chuàng)建一個基于userdataType的userdata,其中保護了指向T對象的指針

                 static int new_T(lua_State *L)

                 {

                     lua_remove(L, 1);   // use classname:new(), instead of classname.new()

                     T *obj = new T(L); // call constructor for T objects

                     userdataType *ud =

                          static_cast<userdataType*>(lua_newuserdata(Lsizeof(userdataType)));

                     ud->pT = obj// store pointer to object in userdata

                     luaL_getmetatable(LT::className); // lookup metatable in Lua registry

                     lua_setmetatable(L, -2);

                     return 1; // userdata containing pointer to T object

                 }

             

            5. 當腳本中指定函數(shù)被調(diào)用的時候,比如b:deposit(50.30)的時候,b是userdata,它的metatable的__index和tbClass綁定(見4),所以會調(diào)用到tbClass的相應(yīng)成員,就是之前關(guān)聯(lián)的thunk:這個時候L的堆棧里面有這個函數(shù)的兩個參數(shù),一個是b本身,一個是50.30。b是userdata,可以根據(jù)它取出對象的指針。見第4步。另外函數(shù)被調(diào)用的時候,它相關(guān)的upvalue也可以取得到,見步驟3。有了對象指針和相應(yīng)的函數(shù),調(diào)用也不為難了,記住參數(shù)50.30是保存在堆棧中傳給類的成員函數(shù)來取得。

            // 所有成員函數(shù)都會調(diào)用到這里,然后根據(jù)upvalue來執(zhí)行具體的成員函數(shù)

                 static int thunk(lua_State *L)

                 {

                     // stack has userdata, followed by method args

                     T *obj = check(L, 1); // the object pointer from the table at index 0.

                     lua_remove(L, 1); // remove self so member function args start at index 1

                     // get member function from upvalue

                     RegType *l = static_cast<RegType*>(lua_touserdata(Llua_upvalueindex(1)));

                     return (obj->*(l->mfunc))(L); // call member function

                 }

                 // 根據(jù)指定位置narg獲得對象指針,這個userdata是在new_T的時候創(chuàng)建的

                 static T *check(lua_State *Lint narg)

                 {

                     void *pUserData = luaL_checkudata(LnargT::className);   

                     userdataType *ud = static_cast<userdataType*>(pUserData);    // 這個是函數(shù)的upvalue

                     if(!ud)

                          luaL_typerror(LnargT::className);

                     return ud->pT;

                 }

             

            posted on 2014-06-27 15:34 C++技術(shù)中心 閱讀(2176) 評論(0)  編輯 收藏 引用 所屬分類: 其他編程
            成人久久精品一区二区三区| 欧美色综合久久久久久| 久久精品国产亚洲AV不卡| 久久99热精品| 99久久er这里只有精品18| 无码国内精品久久人妻| 国产成人久久精品一区二区三区 | 品成人欧美大片久久国产欧美| 久久精品一本到99热免费| 久久亚洲精品成人av无码网站| 久久久久久曰本AV免费免费| 一本久久a久久精品亚洲| 亚洲国产另类久久久精品小说| 亚洲精品乱码久久久久66| 亚洲精品乱码久久久久久蜜桃图片 | 无码久久精品国产亚洲Av影片 | 久久99国产综合精品| www久久久天天com| 狠狠人妻久久久久久综合| 精品久久久无码中文字幕| 国产精品一区二区久久精品涩爱| 成人午夜精品无码区久久| 国产精品99精品久久免费| 91久久精品视频| 亚洲性久久久影院| 国产情侣久久久久aⅴ免费| 国产视频久久| 久久精品无码一区二区WWW| 久久亚洲精品中文字幕| 一本久久久久久久| 亚洲中文字幕无码久久2020| 久久久久国产精品| 久久婷婷五月综合色奶水99啪| av午夜福利一片免费看久久| 精品久久久久中文字幕一区| 久久人人爽人人爽人人片AV高清| 2022年国产精品久久久久| 久久亚洲中文字幕精品一区四 | 久久精品国产清高在天天线| 香蕉久久夜色精品国产尤物| 久久电影网2021|