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

每天早晨叫醒你的不是鬧鐘,而是夢想

  C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
  62 Posts :: 0 Stories :: 5 Comments :: 0 Trackbacks

常用鏈接

留言簿(1)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

 1. 數組操作:
    在Lua中,“數組”只是table的一個別名,是指以一種特殊的方法來使用table。出于性能原因,Lua的C API為數組操作提供了專門的函數,如:
    void lua_rawgeti(lua_State* L, int index, int key);
    void lua_rawseti(lua_State* L, int index, int key);
    以上兩個函數分別用于讀取和設置數組中的元素值。其中index參數表示待操作的table在棧中的位置,key表示元素在table中的索引值。由于這兩個函數均為原始操作,比涉及元表的table訪問更快。通常而言,作為數組使用的table很少會用到元表。
    見如下代碼示例和關鍵性注釋:

復制代碼
1 #include <stdio.h>  
2
#include <string.h>
3
#include <lua.hpp>
4
#include <lauxlib.h>
5
#include <lualib.h>
6

7
extern "C" int mapFunc(lua_State* L)
8
{
9
//檢查Lua調用代碼中傳遞的第一個參數必須是table。否則將引發錯誤。
10 luaL_checktype(L,1,LUA_TTABLE);
11 luaL_checktype(L,2,LUA_TFUNCTION);
12 //獲取table中的字段數量,即數組的元素數量。
13 int n = lua_objlen(L,1);
14 //Lua中的數組起始索引習慣為1,而不是C中的0。
15 for (int i = 1; i <= n; ++i) {
16 lua_pushvalue(L,2); //將Lua參數中的function(第二個參數)的副本壓入棧中。
17 lua_rawgeti(L,1,i); //壓入table[i]
18 lua_call(L,1,1); //調用function(table[i]),并將函數結果壓入棧中。
19 lua_rawseti(L,1,i); //table[i] = 函數返回值,同時將返回值彈出棧。
20 }
21
22 //無結果返回給Lua代碼。
23 return 0;
24 }
復制代碼

    2. 字符串操作:
    當一個C函數從Lua收到一個字符串參數時,必須遵守兩條規則:不要在訪問字符串時從棧中將其彈出,不要修改字符串。在Lua的C API中主要提供了兩個操作Lua字符串的函數,即:
    void  lua_pushlstring(lua_State *L, const char *s, size_t l);
    const char* lua_pushfstring(lua_State* L, const char* fmt, ...);
    第一個API用于截取指定長度的子字符串,同時將其壓入棧中。而第二個API則類似于C庫中的sprintf函數,并將格式化后的字符串壓入棧中。和sprintf的格式說明符不同的是,該函數只支持%%(表示字符%)、%s(表示字符串)、%d(表示整數)、%f(表示Lua中的number)及%c(表示字符)。除此之外,不支持任何例如寬度和精度的選項。

復制代碼
1 #include <stdio.h>  
2
#include <string.h>
3
#include <lua.hpp>
4
#include <lauxlib.h>
5
#include <lualib.h>
6

7
extern "C" int splitFunc(lua_State* L)
8
{
9 const char* s = luaL_checkstring(L,1);
10 const char* sep = luaL_checkstring(L,2); //分隔符
11 const char* e;
12 int i = 1;
13 lua_newtable(L); //結果table
14 while ((e = strchr(s,*sep)) != NULL) {
15 lua_pushlstring(L,s,e - s); //壓入子字符串。
16 //將剛剛壓入的子字符串設置給table,同時賦值指定的索引值。
17 lua_rawseti(L,-2,i++);
18 s = e + 1;
19 }
20 //壓入最后一個子串
21 lua_pushstring(L,s);
22 lua_rawseti(L,-2,i);
23 return 1; //返回table。
24 }
復制代碼

    Lua API中提供了lua_concat函數,其功能類似于Lua中的".."操作符,用于連接(并彈出)棧頂的n個值,然后壓入連接后的結果。其原型為:
    void  lua_concat(lua_State *L, int n);
    參數n表示棧中待連接的字符串數量。該函數會調用元方法。然而需要說明的是,如果連接的字符串數量較少,該函數可以很好的工作,反之,則會帶來性能問題。為此,Lua API提供了另外一組函數專門解決由此而帶來的性能問題,見如下代碼示例:

復制代碼
1 #include <stdio.h>  
2
#include <string.h>
3
#include <lua.hpp>
4
#include <lauxlib.h>
5
#include <lualib.h>
6

7
extern "C" int strUpperFunc(lua_State* L)
8
{
9
size_t len;
10 luaL_Buffer b;
11 //檢查參數第一個參數是否為字符串,同時返回字符串的指針及長度。
12 const char* s = luaL_checklstring(L,1,&len);
13 //初始化Lua的內部Buffer。
14 luaL_buffinit(L,&b);
15 //將處理后的字符依次(luaL_addchar)追加到Lua的內部Buffer中。
16 for (int i = 0; i < len; ++i)
17 luaL_addchar(&b,toupper(s[i]));
18 //將該Buffer及其內容壓入棧中。
19 luaL_pushresult(&b);
20 return 1;
21 }
復制代碼

    使用緩沖機制的第一步是聲明一個luaL_Buffer變量,并用luaL_buffinit來初始化它。初始化后,就可通過luaL_addchar將一個字符放入緩沖。除該函數之外,Lua的輔助庫還提供了直接添加字符串的函數,如:
    void luaL_addlstring(luaL_Buffer* b, const char* s, size_t len);
    void luaL_addstring(luaL_Buffer* b, const char* s);
    最后luaL_pushresult會更新緩沖,并將最終的字符串留在棧頂。通過這些函數,就無須再關心緩沖的分配了。但是在追加的過程中,緩沖會將一些中間結果放到棧中。因此,在使用時要留意此細節,只要保證壓入和彈出的次數相等既可。Lua API還提供一個比較常用的函數,用于將棧頂的字符串或數字也追加到緩沖區中,函數原型為:
    void luaL_addvalue(luaL_Buffer* b);
    
    3. 在C函數中保存狀態:
    Lua API提供了三種方式來保存非局部變量,即注冊表、環境和upvalue。
    1). 注冊表:
    注冊表是一個全局的table,只能被C代碼訪問。通常用于保存多個模塊間的共享數據。我們可以通過LUA_REGISTRYINDEX索引值來訪問注冊表。

復制代碼
1 #include <stdio.h>  
2
#include <string.h>
3
#include <lua.hpp>
4
#include <lauxlib.h>
5
#include <lualib.h>
6

7
void registryTestFunc(lua_State* L)
8
{
9
lua_pushstring(L,"Hello");
10 lua_setfield(L,LUA_REGISTRYINDEX,"key1");
11 lua_getfield(L,LUA_REGISTRYINDEX,"key1");
12 printf("%s\n",lua_tostring(L,-1));
13 }
14
15 int main()
16 {
17 lua_State* L = luaL_newstate();
18 registryTestFunc(L);
19 lua_close(L);
20 return 0;
21 }
復制代碼

    2). 環境:
    如果需要保存一個模塊的私有數據,即模塊內各函數需要共享的數據,應該使用環境。我們可以通過LUA_ENVIRONINDEX索引值來訪問環境。

復制代碼
1 #include <lua.hpp>  
2
#include <lauxlib.h>
3
#include <lualib.h>
4

5
//模塊內設置環境數據的函數
6
extern "C" int setValue(lua_State* L)
7
{
8
lua_pushstring(L,"Hello");
9
lua_setfield(L,LUA_ENVIRONINDEX,"key1");
10 return 0;
11 }
12
13 //模塊內獲取環境數據的函數
14 extern "C" int getValue(lua_State* L)
15 {
16 lua_getfield(L,LUA_ENVIRONINDEX,"key1");
17 printf("%s\n",lua_tostring(L,-1));
18 return 0;
19 }
20
21 static luaL_Reg myfuncs[] = {
22 {"setValue", setValue},
23 {"getValue", getValue},
24 {NULL, NULL}
25 };
26
27
28 extern "C" __declspec(dllexport)
29 int luaopen_testenv(lua_State* L)
30 {
31 lua_newtable(L); //創建一個新的表用于環境
32 lua_replace(L,LUA_ENVIRONINDEX); //將剛剛創建并壓入棧的新表替換為當前模塊的環境表。
33 luaL_register(L,"testenv",myfuncs);
34 return 1;
35 }
復制代碼

    Lua測試代碼如下。

1 require "testenv" 
2
3 print(testenv.setValue())
4 print(testenv.getValue())
5 --輸出為:Hello

    3). upvalue:
    upvalue是和特定函數關聯的,我們可以將其簡單的理解為函數內的靜態變量。 

復制代碼
1 #include <lua.hpp>  
2
#include <lauxlib.h>
3
#include <lualib.h>
4

5
extern "C" int counter(lua_State* L)
6
{
7
//獲取第一個upvalue的值。
8
int val = lua_tointeger(L,lua_upvalueindex(1));
9
//將得到的結果壓入棧中。
10 lua_pushinteger(L,++val);
11 //賦值一份棧頂的數據,以便于后面的替換操作。
12 lua_pushvalue(L,-1);
13 //該函數將棧頂的數據替換到upvalue(1)中的值。同時將棧頂數據彈出。
14 lua_replace(L,lua_upvalueindex(1));
15 //lua_pushinteger(L,++value)中壓入的數據仍然保留在棧中并返回給Lua。
16 return 1;
17 }
18
19 extern "C" int newCounter(lua_State* L)
20 {
21 //壓入一個upvalue的初始值0,該函數必須先于lua_pushcclosure之前調用。
22 lua_pushinteger(L,0);
23 //壓入閉包函數,參數1表示該閉包函數的upvalue數量。該函數返回值,閉包函數始終位于棧頂。
24 lua_pushcclosure(L,counter,1);
25 return 1;
26 }
27
28 static luaL_Reg myfuncs[] = {
29 {"counter", counter},
30 {"newCounter", newCounter},
31 {NULL, NULL}
32 };
33
34
35 extern "C" __declspec(dllexport)
36 int luaopen_testupvalue(lua_State* L)
37 {
38 luaL_register(L,"testupvalue",myfuncs);
39 return 1;
40 }
復制代碼

    Lua測試代碼如下。

復制代碼
1 require "testupvalue"  
2

3
func = testupvalue.newCounter();
4
print(func());
5
print(func());
6
print(func());
7

8
func = testupvalue.newCounter();
9
print(func());
10 print(func());
11 print(func());
12
13 --[[ 輸出結果為: 14 1 15 2 16 3 17 1 18 2 19 3 20 --]] 
復制代碼
posted on 2014-02-17 17:45 沛沛 閱讀(287) 評論(0)  編輯 收藏 引用 所屬分類: Script
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美高清日韩| 国产精品欧美一区喷水| 久久大综合网| 欧美手机在线| 99精品久久久| 久久午夜av| 在线午夜精品自拍| 欧美精品日韩一本| 亚洲精品久久久蜜桃| 蜜桃伊人久久| 久久中文在线| 亚洲国产精品高清久久久| 久久精品亚洲热| 午夜精品久久久99热福利| 国产精品国产三级国产专区53 | 欧美高潮视频| 亚洲欧洲在线看| 亚洲国产精品999| 久久国产精彩视频| 黑人操亚洲美女惩罚| 久久亚洲一区二区| 久久一区精品| 亚洲精品视频在线观看网站 | 欧美一级在线视频| 狠狠色狠狠色综合日日91app| 久久久欧美一区二区| 久久精品国产亚洲a| 在线观看日韩精品| 亚洲黄色免费电影| 国产精品sm| 欧美在线日韩精品| 久久久精品免费视频| 最新日韩欧美| 亚洲久久一区二区| 国产精品资源在线观看| 六月天综合网| 欧美理论在线| 欧美亚洲视频一区二区| 欧美午夜精品理论片a级按摩 | 久久精品国产77777蜜臀| 欧美人在线观看| 香蕉久久夜色精品| 欧美一区二区三区精品| 在线国产亚洲欧美| 99re6热只有精品免费观看| 国产精品男女猛烈高潮激情| 久久一区二区三区超碰国产精品| 欧美成人乱码一区二区三区| 亚洲无线观看| 久久国产精品99精品国产| 亚洲欧洲一区二区三区在线观看| 一区二区久久| 亚洲国产午夜| 亚洲欧美在线一区二区| 亚洲精品视频在线观看网站| 午夜精品区一区二区三| 91久久夜色精品国产九色| 亚洲一二三四区| 亚洲国产精品一区二区第一页| 一本色道久久综合一区 | 久久在线免费观看视频| 亚洲理伦在线| 国产午夜精品全部视频播放| 99国产精品国产精品毛片| 欧美一级久久| 国产精品久久久久久久久免费樱桃| 亚洲国内欧美| 亚洲精品一区二区三区四区高清| 久久久av毛片精品| 国产一区二区丝袜高跟鞋图片 | 亚洲精品视频在线| 影音先锋久久| 91久久国产精品91久久性色| 国产人妖伪娘一区91| 伊人影院久久| 老司机精品视频网站| 亚洲精品字幕| 亚洲视屏一区| 玖玖在线精品| 国产精品区二区三区日本| 狠狠操狠狠色综合网| 亚洲愉拍自拍另类高清精品| 亚洲国产精品久久久久婷婷老年| 久久亚洲电影| 这里只有视频精品| 亚洲视频免费在线| 久久综合久久综合久久| 国产欧美精品在线播放| 亚洲欧美综合国产精品一区| 国产精品亚洲аv天堂网| 欧美福利一区二区| 亚洲天堂成人在线观看| 久久免费国产精品| 一本一本久久a久久精品综合妖精| 久久久www免费人成黑人精品| 国产一区二区在线观看免费| 久久精品一区中文字幕| 欧美中文字幕在线| 亚洲国产成人在线视频| 亚洲国产91色在线| 欧美日韩成人综合在线一区二区 | 欧美精品日韩三级| 在线视频欧美日韩| 欧美一级网站| 免费黄网站欧美| 亚洲伦理在线免费看| 久久久久久久91| 国产精品高潮呻吟久久av无限| 激情另类综合| 久久久久久久999精品视频| 亚洲先锋成人| 欧美私人网站| 一区二区三区 在线观看视| 亚洲国产精品久久久久| 久久久人成影片一区二区三区观看 | 亚洲欧美日本视频在线观看| 欧美中文字幕久久| 欧美成人首页| 国产一本一道久久香蕉| 国产精品一区视频网站| 国产亚洲a∨片在线观看| 国产伦精品一区| 一区二区三区免费网站| 免费日韩一区二区| 久久精品国产清自在天天线| 免费高清在线一区| 午夜精品久久久久久久久久久久久| 久久久伊人欧美| 欧美色视频日本高清在线观看| 欧美日韩国产二区| 国产私拍一区| 99精品久久免费看蜜臀剧情介绍| 亚洲日本一区二区| 亚洲午夜在线| 亚洲破处大片| 欧美成人中文| 一区二区三区日韩精品视频| 欧美岛国在线观看| 韩国在线视频一区| 老司机成人网| 老司机久久99久久精品播放免费| 国产亚洲一区二区三区在线播放| 夜夜爽夜夜爽精品视频| 午夜精品成人在线视频| 亚洲国产日韩一区| 欧美第一黄色网| 亚洲精品乱码视频| 亚洲国产精品尤物yw在线观看| 一本色道久久88亚洲综合88| 久久免费观看视频| 亚洲美女少妇无套啪啪呻吟| 亚洲影院免费观看| 99精品福利视频| 狠狠狠色丁香婷婷综合久久五月| 一区二区国产日产| 欧美亚洲日本国产| 激情综合视频| 小嫩嫩精品导航| 久久性天堂网| 亚洲免费在线看| 国内一区二区在线视频观看| 久久久久免费视频| 久久影音先锋| 久久久久久久久一区二区| 欧美日韩一级黄| 欧美在线亚洲在线| 欧美日韩日韩| 欧美一区二区精品| 欧美成人一二三| 99re成人精品视频| 亚洲精品裸体| 国产精品久久网| 亚洲精品视频在线看| 欧美日韩精品| 91久久极品少妇xxxxⅹ软件| 国产日韩一区欧美| 亚洲成人在线网| 国产午夜精品全部视频在线播放| 亚洲精品美女久久久久| 欧美亚洲视频| 午夜精品在线| 欧美午夜不卡视频| 亚洲一区日韩在线| 狼人社综合社区| 欧美电影资源| 永久久久久久| 毛片一区二区| 欧美成人激情在线| 国产精品久久久久久久久搜平片| 亚洲精品在线二区| 亚洲免费在线| 国产色综合久久| 亚洲欧美日韩一区在线观看| 亚洲一区二区av电影| 欧美日韩国产在线看| 亚洲欧美日本另类| 久久精品国产99| 国产午夜精品美女视频明星a级| 欧美一区二区三区免费视频| 久久女同精品一区二区|