Lua C Api lua_gettable 、lua_settable 、lua_next使用詳細

7736 ワード

       lua_gettable lua_settable   ,     ,        。
1.lua_gettable


void lua_gettable (lua_State *L, int index);
t[k]の値をスタックに押し込みます.ここで、tは有効インデックスindexが指す値であり、kはスタックトップの値です.この関数はスタック上のkeyをポップアップし、結果をスタック上の同じ位置に置きます.
次に例を示します.
//    key    ,  key 1。    key    ,   lua_pushstring。

lua_pushnumber(L, 1);

// table       , -1  ,            ,   -2 。

// lua_gettable            key   -2    table。

lua_gettable(L, -2);

このときtableの1番目の要素の値がスタックの上部に置かれているので、使いたいように使いましょう.
table要素を取得するには:
*要素のkeyをスタックに押し込みlua_gettable(Lua_state,index)
*文字列インデックスの場合はlua_getfield(Lua_state,index,key)を直接取得し、
例:lua_getfield(stack, -1, "loaded");lua_に等しいpushstring(L,"loaded") lua_gettable(L,-2);
上に述べたのはtableの要素にアクセスする方法ですが、tableのすべての要素をどのように遍歴しますか?
1)tableが連続した整形をkeyとするtableである場合、以下の方法を用いることができる.
int size = lua_objlen(L,-1);//   #table  
for(int i = 1; i <= size; i++)  
{  
lua_pushnumber(L, i);  
lua_gettable(L, -2);  
//  table[i]        
lua_pop(L, 1);//        ,     table    。  
};  

2)tableのkeyが任意の値であれば?次の方法を使用できます.
lua_pushnill(L);  
while(lua_next(L, -2))  
{  
//    -1(  ) ,key -2 。  
lua_pop(L, 1);//        , key            
}  

ここで重点的にlua_について説明しますnext.
スタックトップ要素をkeyとし、前のkeyの値(この値はスタックトップに置かれ、nilであればtableの最初の要素の値が現在取り出されていることを示す)を判断してから、現在のkeyとvalueを得る操作です.
このときまずスタックを突き出し、新しいkeyをスタックに入れ、valueをスタックに入れます.このようにスタックトップはtableで最初に遍歴した要素の値です.この値を使い終わったら、この値をスタックから出して、新しいkeyをスタックの上に置いて、遍歴を続けます.前のキー値から次のキー値が算出されない場合(実際にはキーの数は重要ではありません.nilでなければいいです.nilのためにtableの最初の要素を返すからです)、lua_nextは0を返し,ループを終了する.
2.lua_settable
void lua_settable (lua_State *L, int index);
t[k] = vに等しい動作を行い、ここでtは、所与の有効インデックスindexにおける値であり、vはスタックトップの値を指し、kはスタックトップの下の値である.
この関数は、キーと値をスタックからポップアップします.
           ,lua_settable       value,        key   index   table,           ,   settable  。

3.lua_next
int lua_next (lua_State *L, int index);

スタックからキー(キー)をポップアップし、インデックスで指定したテーブルのキー-valueペアをスタック(キーの後ろの次のペアを指定)に押し込みます.テーブルにより多くの要素がない場合、lua_nextは0(スタックに何も押し込まない)を返します.
典型的な遍歴方法は次のとおりです.
     /* table      't'   */
     lua_pushnil(L);  /*     key */
     while (lua_next(L, t) != 0) {
       /*     'key' (    -2  )   'value' (    -1  ) */
       printf("%s - %s
", lua_typename(L, lua_type(L, -2)), lua_typename(L, lua_type(L, -1))); /* 'value' ; 'key' */ lua_pop(L, 1); }

1枚のテーブルを巡回するときは、このkeyが文字列に違いないことを知らない限り、keyに直接lua_tolstringを呼び出さないでください.呼び出しlua_tolstringは、所与のインデックス位置の値を変更する可能性がある.これは、次の呼び出しlua_nextに影響を与えます.
 
最後に、luaのloadedテーブルをcで呼び出し、ある規則に合致するkeyを設定して、そのvalueをnilに設定します.
 1 ua_getglobal(stack, "package");                         /* L: package,  package,    */
 2 lua_getfield(stack, -1, "loaded");                       /* L: package loaded,   ,   */
 3 lua_pushnil(stack);                                     /* L: package loaded nil */
 4 while ( 0 != lua_next(stack, -2 ) ) /* L: package loaded, key, value,      nil,  nil,       key value,    */
 5 {
 6     //CCLOG("%s - %s 
", tolua_tostring(stack, -2, ""), lua_typename(stack, lua_type(stack, -1)));
7 std::string key=tolua_tostring(stack, -2, ""); /* , key*/ 8 std::string tableKey =key; /* key */ 9 int found = tableKey.rfind(".lua"); 10 if (found!=std::string::npos) 11 tableKey = tableKey.substr(0,found); 12 tableKey=replaceAll(tableKey,".","/"); 13 tableKey=replaceAll(tableKey,"\\","/"); 14 tableKey.append(".lua"); 15 found = fileName.rfind(tableKey); 16 if (0 == found || ( found!=std::string::npos && fileName.at(found-1) == '/')) 17 { 18 lua_pushstring(stack, key.c_str()); /*package loaded, key, value,newkey, key, */ 19 lua_pushnil(stack); /* pakage,loaded(table)(-5),key(-4),value(-3),key(-2),nil(-1)*/ 20 if (lua_istable(stack, -5)) /* table*/ 21 { 22 /* key nil*/ 23 lua_settable(stack, -5);/*pakage,loaded(table),key,value, key value table, */ 24 } 25 } 26 lua_pop(stack, 1); /*pakage,loaded(table),key value, key next*/ 27 } 28 lua_pop(stack, 2); /* */