青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 311, comments - 0, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

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

Posted on 2012-07-11 16:43 點點滴滴 閱讀(362) 評論(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);
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美日韩日本国产亚洲在线| 一卡二卡3卡四卡高清精品视频| 国产精品久久久久久久久久妞妞 | 亚洲国内在线| av不卡免费看| 亚洲激精日韩激精欧美精品| 亚洲国产欧美一区二区三区同亚洲| 国产在线欧美日韩| 亚洲激情亚洲| 日韩午夜黄色| 午夜精品久久久久影视| 欧美在线视频一区二区三区| 日韩视频免费| 亚洲一级影院| 久久av资源网站| 开心色5月久久精品| 欧美xxxx在线观看| 99国产精品国产精品毛片| 一区二区日韩精品| 亚洲一区二区视频在线| 久久久一区二区| 欧美日韩国产一区| 极品少妇一区二区三区| 99国产精品99久久久久久| 欧美一区二区视频97| 麻豆91精品| 一区二区三区免费观看| 久久国产一区二区| 久久免费高清| 国产精品久久久久一区二区三区共 | 久久在线精品| 亚洲国产成人一区| 欧美专区18| 欧美日韩亚洲综合一区| 亚洲第一毛片| 亚洲一区二区3| 久久最新视频| 午夜日韩电影| 国产精品美女午夜av| 亚洲精品综合精品自拍| 蜜臀av国产精品久久久久| 一区二区三区 在线观看视频| 免费不卡在线观看av| 精品二区视频| 久久精品国产亚洲一区二区三区 | 国产精品美女久久久浪潮软件| 亚洲激情黄色| 久久人人精品| 亚洲欧美国产日韩中文字幕| 欧美日韩一卡二卡| 日韩午夜av| 欧美韩国一区| 老司机精品导航| 在线观看91精品国产入口| 欧美在线观看你懂的| 这里只有精品丝袜| 欧美日韩精品一区二区| 一本久久a久久精品亚洲| 欧美激情一区二区三区| 久久五月天婷婷| 在线欧美影院| 老司机午夜精品| 久久综合九色综合久99| 亚洲高清在线| aa级大片欧美三级| 欧美中文在线视频| 国产欧美亚洲视频| 亚洲欧美自拍偷拍| 宅男精品导航| 国产日韩欧美自拍| 久久激情综合| 欧美在线观看你懂的| 国产视频一区在线| 香蕉久久夜色精品| 亚洲天天影视| 国产精品午夜在线| 亚洲视频你懂的| 亚洲蜜桃精久久久久久久| 欧美日韩中文字幕日韩欧美| 一本久道综合久久精品| 在线视频精品一| 国产精品永久入口久久久| 久久av一区二区三区| 欧美中文字幕不卡| 在线电影一区| 亚洲精品视频在线| 国产精品久久久久久久久久久久| 亚洲欧美日韩一区二区在线 | 亚洲人成绝费网站色www| 亚洲激情六月丁香| 欧美天堂亚洲电影院在线观看| 亚洲一区免费在线观看| 久久精品99国产精品日本| 亚洲国产影院| 亚洲一品av免费观看| 尤物九九久久国产精品的分类| 亚洲人成在线播放网站岛国| 国产伦精品一区二区三区在线观看| 久久视频一区| 欧美久久久久中文字幕| 亚洲欧美日韩综合aⅴ视频| 欧美一区激情| 日韩视频在线一区二区| 亚洲尤物影院| 亚洲电影视频在线| 亚洲一区二区影院| 在线日韩电影| 午夜精品久久一牛影视| 亚洲欧洲日产国码二区| 亚洲欧美日本精品| 亚洲精品欧美在线| 欧美亚洲一区二区三区| 亚洲美女黄色| 久久人人九九| 午夜精品久久久久久久久| 欧美 日韩 国产精品免费观看| 欧美中文字幕在线视频| 欧美激情亚洲激情| 久久久久一区二区三区| 国产精品另类一区| 老司机午夜精品视频在线观看| 欧美日韩中文字幕| 亚洲第一精品电影| 国内精品视频在线播放| 一本一本久久| 美女在线一区二区| 欧美成人国产一区二区| 久久亚洲精品中文字幕冲田杏梨| 欧美日韩精品免费在线观看视频| 免费亚洲一区| 在线观看91久久久久久| 午夜天堂精品久久久久| 亚洲自拍高清| 欧美午夜剧场| 亚洲美女在线视频| 一区二区高清视频| 欧美**人妖| 欧美电影在线免费观看网站| 精品电影在线观看| 久久成人免费日本黄色| 久久久午夜视频| 极品日韩久久| 久久久国产午夜精品| 美国十次了思思久久精品导航| 国产日产亚洲精品系列| 亚洲欧美中文日韩在线| 欧美在线精品一区| 国产一区二区三区av电影 | 久久国产精品久久久久久| 欧美一区永久视频免费观看| 国产毛片一区二区| 久久久精品国产免费观看同学| 欧美jizzhd精品欧美巨大免费| 亚洲人成人一区二区三区| 欧美深夜影院| 狠狠操狠狠色综合网| 久久久.com| 91久久精品美女| 亚洲一级在线观看| 国产视频在线观看一区| 久久综合伊人77777麻豆| 亚洲人成在线影院| 午夜精品免费在线| 亚洲成人资源网| 欧美日本中文| 午夜精品久久| 欧美激情中文不卡| 性高湖久久久久久久久| 亚洲福利国产精品| 欧美日韩中文字幕精品| 久久国产手机看片| 亚洲伦伦在线| 久久男人av资源网站| 一区二区三区视频在线播放| 国产精品视频成人| 久久综合伊人77777蜜臀| 亚洲午夜视频| 欧美黄色影院| 久久精品国产亚洲aⅴ| 日韩网站免费观看| 精品999日本| 国产精品青草久久| 欧美精品二区三区四区免费看视频| 欧美一区不卡| 一区二区久久| 亚洲国产精品一区二区尤物区| 亚洲在线播放| 日韩视频一区二区三区| 国内不卡一区二区三区| 欧美视频一区二区在线观看 | 欧美黄色视屏| 久久久综合网| 欧美一级欧美一级在线播放| 99国产精品久久久久久久成人热| 老鸭窝亚洲一区二区三区| 亚洲尤物视频网| 欧美激情1区2区| 欧美在线视频不卡| 亚洲视频一区| 日韩视频永久免费|