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); /* */