• <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>
            posts - 311, comments - 0, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            (搬運工)Lua5.1的常用API

            Posted on 2012-07-11 16:43 點點滴滴 閱讀(351) 評論(0)  編輯 收藏 引用 所屬分類: 02 編程語言

            lua_State
                        Lua狀態機或叫Lua虛擬機,支持多線程,可創建多個狀態機
                        typedef int (*lua_Cfunction)(lua_State* L)
                        Lua所調用的C函數的函數原型,在C程序中需要將這種函數類型的
                        函數注冊到Lua狀態機中,此后Lua才能調用到C的函數
                        如果有函數
                        int c_Hello(lua_State* l)
                        {
                           luaL_checktype(l, 1, LUA_TSTRING)
                           luaL_checktype(l, 2, LUA_TSTRING)    // 兩個參數都是字符串
                            // 先輸出第二個參數,后輸出第一個參數
                         printf("%s\t%s\n", lua_tostring(l,-1),lua_tostring(l, -2));
                  }

                        需在C程序初始化的時候執行以下代碼:
                                // 將函數名壓入LuaVM棧
                                lua_pushstring(l, "c_hello");
                                // 將函數地址壓入LuaVM棧
                                lua_pushcclosure(l, &c_Hello, 0)
                                // 把LuaVM棧上的這個表放入全局表中
                                lua_settable(l, LUA_GLOBALSINDEX)
                        此后在Lua中就可以這樣調用:
                                c_hello()

                        注:C函數的實現如果有參數的話最好為每一個參數進行類型檢查
                                以確保所棧里的參數是函數參數類型匹配

                lua_State* lua_newstate(lua_Alloc f, void* ud)
                        新建一個LuaVM,可以直接調用lua_open來調用這個函數

                void lua_close(lua_State* l))
                        關閉LuaVM


                關于棧幀
                        當一個函數調用發生的時候就形成了一個棧幀,當這個函數調用結束
                        后這個棧幀就消失了

                        如在Lua這樣調用c_hello("Hello", "World"),那么c_Hello所看到
                        棧幀就是從它的參數開始,如下圖:
                        可以有兩種索引方式對棧頂進行操作,正數和負數。    



                棧相關操作
                        int (lua_gettop) (lua_State *L)
                                取得當前使用了多少棧空間
                        void (lua_settop) (lua_State *L, int idx)
                                把棧頂設置在idx處,相當于做了一次函數調用改變了棧幀
                                如果這個時候調用 lua_settop(L, 1),則會把剛壓入棧的兩個參數刪除
                        void (lua_pushvalue) (lua_State *L, int idx)
                                向此棧幀的第idx個位置的值壓入棧頂,相當于復制
                        void (lua_remove) (lua_State *L, int idx)
                                刪除第idx個位置的值
                                如果lua_remove(L, -2)則會將"Hello"刪除而剩下"World"在棧頂
                                并會被移到原來"Hello"存放的位置
                        void (lua_insert) (lua_State *L, int idx);
                                先將整個上移或下移,并將棧頂的值壓入空出的位置
                        void (lua_replace) (lua_State *L, int idx)
                                把棧頂的值替換掉idx處的值
                        int (lua_checkstack) (lua_State *L, int sz)
                                檢查棧的大小是否已經增長到最大值,如果沒有則將棧的大小增長sz
                                返回0表示棧溢出,返回1表示成功
                        void (lua_xmove) (lua_State *from, lua_State*to, int n)
                                從LavVM的棧頂移動n個值到to的LuaVM的棧頂


                棧存取操作
                        以下函數往棧頂壓入一個C值
                        void (lua_pushnil) (lua_State *L)
                                往棧頂壓入一個NIL值
                        void (lua_pushnumber) (lua_State *L, lua_Number n)
                                往棧頂壓入一個實數
                        void (lua_pushinteger) (lua_State *L,lua_Integer n)
                                往棧頂壓入一個整數
                        void (lua_pushlstring) (lua_State *L, const char*s, size_t l)
                                往棧頂壓入一個二進制串
                        void (lua_pushstring) (lua_State *L, const char*s)
                                往棧頂壓入一個字符串
                        const char *(lua_pushvfstring) (lua_State *L,const char *fmt, va_list argp)
                                往棧頂壓入一個格式化串,不過argp是變參
                        const char *(lua_pushfstring) (lua_State *L,const char *fmt, ...)
                                往棧頂壓入一個格式化串
                        void (lua_pushcclosure) (lua_State *L,lua_CFunction fn, int n)
                                壓入一個函數
                        void (lua_pushboolean) (lua_State *L, int b)
                                往棧頂壓入一個bool類型
                        void (lua_pushlightuserdata) (lua_State *L, void*p)
                                往棧頂壓入一個數組,數組的內存塊指向p
                        int (lua_pushthread) (lua_State *L)


                        以下函數往從棧中復制一個值存入棧頂
                        void (lua_gettable) (lua_State *L, int idx)
                                idx指向表在棧中的位置,彈出棧頂的key取得表中的值并壓入棧頂
                                此函數與lua_rawget的區別在于此函數會調用metatable的方法
                        void (lua_getfield) (lua_State *L, int idx,const char *k)
                                以k所在棧中的索引(idx)作為參數,取得k對應的值并壓入棧頂
                                效率與lua_gettable相同
                        void (lua_rawget) (lua_State *L, int idx)
                                idx指向表在棧中的位置,彈出棧頂的key取得表中的值并壓入棧頂
                                為了提高數據訪問的效率而直接讀取表中的數據,不需要對metamethod的調用
                                這個函數在循環訪問數組元素比較方便
                        void (lua_rawgeti) (lua_State *L, int idx, intn)
                                idx指向表在棧中的位置,n指向key在棧中的位置,取得表中的值并入棧
                                相當于:lua_pushnumber(L,n);lua_rawget(L,idx)
                        void (lua_createtable) (lua_State *L, int narr,int nrec)
                                新建一個表并壓入棧頂,表的大小為narr,并預留了nrec個元素空間
                        void *(lua_newuserdata) (lua_State *L, size_t sz)
                                在棧中分配一塊大小為sz的內存并把管理結構入棧且返回內存地址
                        int (lua_getmetatable) (lua_State *L, intobjindex)
                                objindex指向對象在棧中的位置,取得對象的metatable并將其壓入棧頂
                                如果失敗或者對象沒有metatable表則返回0
                        void (lua_getfenv) (lua_State *L, int idx)
                                idx指向對象所在棧中的位置,取得此對象并將其環境量壓入棧

                        以下函數用于判斷棧內某處值的類型
                        int (lua_isnumber) (lua_State *L, int idx)
                                棧idx處的值是否是實數
                        int (lua_isstring) (lua_State *L, int idx)
                                棧idx處的值是否是字符串
                        int (lua_iscfunction) (lua_State *L, int idx)
                                棧idx處的值是否是函數
                        int (lua_isuserdata) (lua_State *L, int idx)
                                棧idx處的值是否是二進制數據
                        int (lua_type) (lua_State *L, int idx)
                                取得棧idx處的值的類型
                        const char *(lua_typename) (lua_State *L, inttp)
                                將類型轉換成C字符串
                        int (lua_equal) (lua_State *L, int idx1, intidx2)
                                棧內兩個值是否相等,類型和值都需要相等才返回真
                        int (lua_rawequal) (lua_State *L, int idx1, intidx2)
                                棧內兩個對象是否相等,如果是對象時所指對象相同也算相等
                        int (lua_lessthan) (lua_State *L, int idx1, intidx2)
                                棧內兩個值的大小,idx1處的值是否小于idx2處的值

                        以下函數將棧內的某個格轉換成C能理解的值,棧結構不變
                        lua_Number (lua_tonumber) (lua_State *L, intidx)
                                將idx所指向的Lua值轉換成實數返回
                        lua_Integer (lua_tointeger) (lua_State *L, intidx)
                                將idx所指向的Lua值轉換成整數返回
                        int (lua_toboolean) (lua_State *L, int idx)
                                將idx所指向的Lua值轉換成bool值返回
                        const char *(lua_tolstring) (lua_State *L, intidx, size_t *len)
                                將idx所指向的Lua值轉換成字符串返回,并把長度存入len中
                        size_t (lua_objlen) (lua_State *L, int idx)
                                取得idx所指向的Lua值長度
                        lua_Cfunction (lua_tocfunction) (lua_State *L,int idx)
                                將idx所指向的Lua值轉換成函數返回
                        void *(lua_touserdata) (lua_State *L, int idx)
                                將idx所指向的Lua值轉換成內存塊(數組)返回
                        lua_State *(lua_tothread) (lua_State *L, intidx)
                                將idx所指向的Lua值轉換成LuaVM對象返回
                        const void *(lua_topointer) (lua_State *L, intidx)
                                取得idx所指對象的值的存儲地址返回

                        以下函數與其對應的get函數類似
                        void (lua_settable) (lua_State *L, int idx)
                        void (lua_setfield) (lua_State *L, int idx,const char *k)
                        void (lua_rawset) (lua_State *L, int idx)
                        void (lua_rawseti) (lua_State *L, int idx, intn)
                        int (lua_setmetatable) (lua_State *L, intobjindex)
                        int (lua_setfenv) (lua_State *L, int idx)

                函數調用
                  關于函數調用
                      當需要調用一個Lua函數時,先要將函數壓入棧中,然后將其參數依次壓入
                        如下圖:

                         假設在Lua代碼中有函數:
                            function hello(x, y)
                              print(x, y)
                            end
                            則在C中可以這樣來調用:
                           lua_getglobal(L, "hello"); -- 從全局域中取得hello函數并壓入棧頂
                            lua_pushstring(L, "Hello"); -- 依次壓入兩個參數
                           lua_pushstring(L, "World");    
                            lua_call(L, 2, 0); -- 跳過兩個參數取得函數并調用此函數,函數中會取得相應參數
                                                
                        void (lua_call) (lua_State *L, int nargs, intnresults)
                                無保護的函數調用
                                nargs是指調用函數的參數個數,nresults是指所調用的函數的返回值個數
                        int (lua_pcall) (lua_State *L, int nargs, intnresults, int errfunc)
                                與lua_call相似,不過此函數是在保護模式下被調用
                                如果發生錯誤則會將錯誤壓入棧,否則功能與lua_call一樣
                        int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud)
                                直接調用一個C函數,并把ud做為func函數調用的參數
                                也就是說在func函數內部看來第一個參數是ud
                        int (lua_load) (lua_State *L, lua_Reader reader,void *dt, const char *chunkname);
            久久人人爽爽爽人久久久| 久久精品综合网| 久久国产精品久久| 久久91这里精品国产2020| 热综合一本伊人久久精品| 久久精品国产男包| 久久这里只有精品首页| 无码任你躁久久久久久久| 久久综合综合久久综合| 成人国内精品久久久久影院VR| 久久亚洲精品无码播放| 99久久精品国产麻豆| 精品久久久久久无码中文野结衣 | 99国产欧美精品久久久蜜芽| 久久精品成人一区二区三区| 婷婷五月深深久久精品| 午夜福利91久久福利| 久久不射电影网| 久久精品麻豆日日躁夜夜躁| 久久嫩草影院免费看夜色| 国产精品久久国产精麻豆99网站| 无码国内精品久久人妻麻豆按摩 | 亚洲国产成人久久精品动漫| 99精品国产99久久久久久97| 色综合久久久久综合99| 国产激情久久久久影院老熟女免费 | 久久综合九色综合网站| 久久亚洲中文字幕精品一区四| 精品亚洲综合久久中文字幕| 综合久久国产九一剧情麻豆| 综合久久精品色| 蜜臀久久99精品久久久久久| 久久久WWW成人| 久久久久亚洲av毛片大| 久久亚洲AV永久无码精品| 久久国产精品无码网站| 久久久这里有精品中文字幕| 久久亚洲2019中文字幕| 中文字幕无码久久精品青草| 久久亚洲精品成人无码网站| 久久天天婷婷五月俺也去|