linux 進階2--C++讀取lua文件中的變量、一維表、二維表

lua 語言非常靈活,一般把lua 作爲腳本文件,會用C++與之進行交互。最重要的是C++代碼能讀取到腳本中的變量、一維表、二維表。

這樣有些參數就可以在lua文件進行更改,而不用重新更改C++代碼、又得重新編譯、運行。

lua 文件 (test.lua )中的內容如下

-- ship include name width  height 
yValue = 60
myStr = "guoyilongedu"
--one 
cfg = {name = "test123" ,rotation = 180 , width = 123}
myShip = {}
for indx = 1,10 do
local mystring = string.format("%s%d","id",indx)
myShip[indx] = {}
myShip[indx].name =  mystring
myShip[indx].width = 140
myShip[indx].height =100
end
for index = 1,table.getn(myShip) do
  print(index,myShip[index].name,myShip[index].width,myShip[index].height)
end
for index ,value in pairs(cfg) do
 print(index,value)
end
print(yValue);


如上面文件中的內容, yValue , myStr 就是lua 文件中的變量,cfg 是一維表 myShip 是二維表

#include <stdio.h>
extern "C"{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
/*Lua 解釋器指針
 */
int main ( int argc, char *argv[] ){
 lua_State* L;
/*初始化Lua
 */
 L=lua_open();

 luaopen_base(L);
 luaopen_table(L);
 luaopen_string(L);
 luaopen_math(L);
 lua_pushcfunction(L,l_getarr);
 lua_setglobal(L,"getarr");
 
 /*運行腳本
 */
 if (luaL_dofile(L, "test.lua"))
 {
   printf("run script failed\n");
 }
 else
 {
 /* lua_getglobal(L,"result");
   if(lua_isnumber(L,-1))
    {
     printf("The result of the lua script is %d\n",lua_tonumber(L,-1));
    }
  */
  printf("輸出變量\n");
  lua_getglobal(L,"yValue");
  if(lua_isnumber(L,-1))
   {
      printf("%s","ddddd\n");
      printf("%d",(int)lua_tointeger(L,-1));
   }
  lua_getglobal(L,"myStr");
  if(lua_isstring(L,-1))
  {
    printf("%s","\n");
    printf("%s\n",lua_tostring(L,-1));
  }
  /* 讀取一維表
  */
  lua_getglobal(L,"cfg");
  if(lua_istable(L,-1))
  {
    lua_pushstring(L,"name");
    lua_gettable(L,-2);
     if(lua_isstring(L,-1))
      {
       printf("%s  %s\n","name",lua_tostring(L,-1));
      }
    lua_pop(L,1); 
    lua_pushstring(L,"rotation");
    lua_gettable(L,-2);
     if(lua_isnumber(L,-1))
      {
       printf("%s  %d\n","rotation",(int)lua_tonumber(L,-1));
      }
     //清空棧
    lua_pop(L,2);
  }
   //用遍歷的方式訪問一維表
  lua_getglobal(L,"cfg");
  int t_idx=lua_gettop(L);
  lua_pushnil(L);
  printf("%s\n","用遍歷的方式訪問一維表");
  while(lua_next(L,t_idx)!=0)
  {
   // printf("%s %s\n",lua_typename(L,lua_type(L,-2)),lua_typename(L,lua_type(L,-1)));
    if(lua_isstring(L,-2))
     {
      printf("%s\n",lua_tostring(L,-2));
     }
    else if(lua_isnumber(L,-2))
     {
       printf("%d\n",(int)lua_tonumber(L,-2));
     } 

    if(lua_isstring(L,-1))
     {
      printf("%s\n",lua_tostring(L,-1));
     }
    else if(lua_isnumber(L,-1))
     {
       printf("%d\n",(int)lua_tonumber(L,-1));
     } 

 //  printf("%s\n",lua_tostring(L,-2));
  //  printf("%s\n",lua_tostring(L,-1));
    lua_pop(L,1);
  }
  //二維表的遍歷
   printf("二維表的遍歷\n");
   int it_idx;
  lua_getglobal(L,"myShip");
 
  t_idx=lua_gettop(L);
  lua_pushnil(L);
  while(lua_next(L,t_idx))
   {
     it_idx=lua_gettop(L);
      lua_pushnil(L);
       while(lua_next(L,it_idx))
         {
             printf("%s= ",lua_tostring(L,-2));
               printf("%s\n",lua_tostring(L,-1));
               lua_pop(L,1);
         }
       lua_pop(L,1);
   }
   
  
 /* while (lua_next(L,-1))
    {
     lua_pushvalue(L,-2);
     const char * key =lua_tostring(L,-1);
     const char * value = lua_tostring(L,-2);
     printf("%s => %s\n",key ,value);
     lua_pop(L,2);
    }*/
 }

/*清除Lua
 */
 lua_close(L);

 return 0;

}


輸出變量 

  lua_getglobal(L,"yValue");  //得到變量
    if(lua_isnumber(L,-1)) //如果是數字
     {
         printf("%s","ddddd\n");
        printf("%d",(int)lua_tointeger(L,-1));
     }

     lua_getglobal(L,"myStr");  //得到變量

      if(lua_isstring(L,-1))  //如果是字符串

        { printf("%s","\n");

              printf("%s\n",lua_tostring(L,-1));

      }
輸出一維表

  lua_getglobal(L,"cfg");  //得到一維表變量 cfg
  if(lua_istable(L,-1)) //如果是table
  {
    lua_pushstring(L,"name");  //將key name 入棧
    lua_gettable(L,-2); //table 就在-2的位置
     if(lua_isstring(L,-1))
      {
       printf("%s  %s\n","name",lua_tostring(L,-1));
      }
    lua_pop(L,1);

    /*

    Lua取元素的協議是:首先將一個字符串壓棧,然後調用lua_gettable。
lua_gettable的實際的工作流程是:以棧頂的字符串(key)爲關鍵字,在棧索引位置( -2)的表(table)中查詢該關鍵字的值(value),然後將棧頂的key出棧,再將value壓棧。

  lua_pop( L, 1)的作用就是將這個返回值出棧,以保持棧的原貌

*/


    lua_pushstring(L,"rotation");
    lua_gettable(L,-2);
     if(lua_isnumber(L,-1))
      {
       printf("%s  %d\n","rotation",(int)lua_tonumber(L,-1));
      }
     //清空棧
    lua_pop(L,2);
  } 

 上面只是在知道key 的情況下,比較有用,當然也可以用遍歷的方式來獲取

  lua_getglobal(L,"cfg"); //得到變量cfg
  int t_idx=lua_gettop(L); //得 cfg 的長度
  lua_pushnil(L);  //往棧頂壓入nil
  printf("%s\n","用遍歷的方式訪問一維表");

  while(lua_next(L,t_idx)!=0) // 開始遍歷
  {
       if(lua_isstring(L,-2)) //返回值位於-2的位置 是value
     {
      printf("%s\n",lua_tostring(L,-2));
     }
    else if(lua_isnumber(L,-2))
     {
       printf("%d\n",(int)lua_tonumber(L,-2));
     }

    if(lua_isstring(L,-1)) //返回值位於-1的位置 是key
     {
      printf("%s\n",lua_tostring(L,-1));
     }
    else if(lua_isnumber(L,-1))
     {
       printf("%d\n",(int)lua_tonumber(L,-1));
     }

     lua_pop(L,1);
  }

二維表的遍歷類似於一維表 只是多了層嵌套而已

    printf("二維表的遍歷\n");
   int it_idx;
  lua_getglobal(L,"myShip");
 
  t_idx=lua_gettop(L);
  lua_pushnil(L);
  while(lua_next(L,t_idx))
   {
     it_idx=lua_gettop(L);
      lua_pushnil(L);
       while(lua_next(L,it_idx))
         {
             printf("%s= ",lua_tostring(L,-2));
               printf("%s\n",lua_tostring(L,-1));
               lua_pop(L,1);
         }
       lua_pop(L,1);
   }

 我也是剛剛學lua 還不是很熟悉,尤其是棧這一塊,目前只能做到用,滿足要求,很難明白得透徹,還得靠以後多用,多領悟

下面是我參照別人的鏈接 

 http://www.360doc.com/content/11/1225/12/1317564_174844311.shtml

 

這圖就是 遍歷一維表的大致過程 是從別人那裏摘取,還得謝謝他

 

 

 

 

 

 

 

 

 

 

 

發佈了60 篇原創文章 · 獲贊 32 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章