Lua笔记----C++调用Lua脚本中二维table的数据


用Lua里的table可以实现C++中的数组。Lua的作用一般是用来配置。我把配置的东西写在lua的table里。现在我想要在C++中调用lua中的table,从而把数据传到C++的数组中。
 
先搞一个一维的table。我是看了《lua程序设计第二版》的25.2节。貌似没有API直接能够取直接取得table的值。或者我不知道吧。书上是用一个getfield函数实现。也就是可能要根据自己的需要重写它。于是模仿的写一个。

相关链接:Lua程序设计(第2版)中文 PDF 

作用是取得table[key]的值

  1. int getfield(lua_State *L,int key)
  2. {
  3. int result = 0;
  4. lua_pushnumber(L,key);
  5. lua_gettable(L,-2);
  6. if (!lua_isnumber(L,-1))
  7. cout<<"error"<<endl;
  8. result = (int)lua_tonumber(L,-1);
  9. lua_pop(L,1);
  10. return result;
  11. }

虽然代码最终运行成功。但是过程中,各种bug

在书上找到一个函数

  1. staticvoid stackDump(lua_State *L);

作用是打印交换栈里的数据。

有了这个函数之后,我们对交换栈里的数据情况,就看得一清二楚了。

//完整代码

  1. #include <iostream>
  2. #include <stdio.h>
  3. usingnamespace std;
  4. extern"C"
  5. {
  6. #include "lua.h"
  7. #include "lualib.h"
  8. #include "lauxlib.h"
  9. };
  10. lua_State *L;
  11. staticvoid stackDump(lua_State *L)
  12. {
  13. int top = lua_gettop(L);
  14. for (int i = 1; i <= top; i++)
  15. {
  16. int t = lua_type(L,i);
  17. switch(t)
  18. {
  19. case LUA_TSTRING:
  20. printf("'%s'",lua_tostring(L,i));
  21. break;
  22. case LUA_TBOOLEAN:
  23. printf(lua_toboolean(L,i)?"true":"false");
  24. break;
  25. case LUA_TNUMBER:
  26. printf("%g",lua_tonumber(L,i));
  27. break;
  28. default:
  29. printf("%s",lua_typename(L,t));
  30. }
  31. printf(" ");
  32. }
  33. printf("\n");
  34. }
  35. int getfield(lua_State *L,int key)
  36. {
  37. int result = 0;
  38. lua_pushnumber(L,key);
  39. cout<<"pushnmber : ";
  40. stackDump(L);
  41. cout<<"gettable : ";
  42. lua_gettable(L,-2);
  43. stackDump(L);
  44. if (!lua_isnumber(L,-1))
  45. cout<<"error"<<endl;
  46. result = (int)lua_tonumber(L,-1);
  47. cout<<"lua_tonumber : ";
  48. stackDump(L);
  49. lua_pop(L,1);
  50. cout<<"lua_pop : ";
  51. stackDump(L);
  52. return result;
  53. }
  54. int main()
  55. {
  56. L = lua_open();
  57. luaL_openlibs(L);
  58. luaL_dofile(L,"test.lua");
  59. cout<<"start : ";
  60. stackDump(L);
  61. lua_getglobal(L,"a");
  62. cout<<"getglobal : ";
  63. stackDump(L);
  64. for (int i = 1; i <= 3; i++)
  65. {
  66. cout<<"result:"<<getfield(L,i)<<endl;
  67. }
  68. cout<<endl;
  69. system("pause");
  70. lua_close(L);
  71. return 0;
  72. }

 

//test.lua

a = {11,12,13}

截图看下结果。

 

最右是栈顶。数据变化很清楚。Getfield函数式假设table已经在栈顶。所以我们在前面必须先用lua_getglobal把table放到栈顶。Pushnumber会把数据压栈。接着gettable会取栈顶的数据,根据给出的table位置,这里是-2,计算出table[栈顶]的数据,把它压栈。Pop则是从栈里退出数据,恢复到一开始的状态。

  • 1
  • 2
  • 下一页

相关内容