找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3768|回复: 0

Lua学习笔记——Lua作为库嵌入到C

[复制链接]
发表于 2012-1-17 10:08:35 | 显示全部楼层 |阅读模式
/*C++程序接收用户输入的字符串,把该字符串作为Lua的一个chunk送到stack中编译执行。*/
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <lua.hpp>
  4. int main(int argc, char* argv[]){
  5.         char buff[256];
  6.         int error = 0;
  7.         lua_State* L=lua_open();
  8.         if(0 == L){
  9.                 return -1;
  10.         }
  11.         luaL_openlibs(L);
  12.        
  13.         while (fgets(buff, sizeof(buff), stdin) != 0){
  14.                 error = luaL_loadbuffer(L, buff, strlen(buff), \
  15.                         "line") || lua_pcall(L, 0, 0, 0);
  16.                 if(error){
  17.                         fprintf(stderr, "%s", lua_tostring(L, -1));
  18.                         lua_pop(L, 1);
  19.                 }
  20.         }
  21.         lua_close(L);
  22.         return 0;
  23. }
复制代码
  1. /*
  2. 函数luaL_loadbuffer编译一段字符串为chunk, lua_pcall执行chunk.
  3. lua_tostring(L, -1)拿到栈顶元素,并将其转换为字符串
  4. */
  5. /*
  6. @param errfunc if errfunc is 0, then error message returned on the stack is exactly the original error message. otherwise, errfunc is the stack index of an error handler function.In case of runtime errors, this function will be called with error message and its return value  will be the message returned on the stack by lua_pcall.
  7. @return zero in case of success or one of the following error codes(definded in lua.h)
  8. LUA_ERRRUN, LUA_ERRMEM, LUA_ERRERR
  9. int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc)
  10. Loads a buffer as a Lua chunk.
  11. @param name is the chunk name.
  12. @return the same with lua_load function. 0 in case of success or LUA_ERRSYNTAX, LUA_ERRMEM.
  13. int luaL_loadbuffer(lua_State* L, const char* buff, size_t sz, const char* name)
  14. Changes in the API(Lua 5.1)
  15. --The luaopen_* functions(to open libraries) cannot be  called directly, like a regular C function. They must be called through Lua, like a Lua function.
  16. --Function lua_open was replaced by lua_newstate to allow the user to set a memory-allocation function. You can use luaL_newstate from the standard library to create a state with a standard allocation function (based on realloc)
  17. --Functions luaL_getn and luaL_setn are deprecated. Use lua_objlen instead of luaL_getn and nothing instead of luaL_setn.
  18. --Function luaL_checkudata now throws an error when the given value is not a userdata of expected type. (In Lua5.0 it returned NULL)
  19. */
  20. /*
  21. class Uncopyable{
  22. public:
  23.         virtual ~Uncopyable();
  24. protected:
  25.         Uncopyable();
  26. private:
  27.         Uncopyable(const Uncopyable& rhs);
  28.         Uncopyable& operator=(const Uncopyable& rhs);
  29. };
  30. class Uninheritable{
  31. public:
  32.         Uninheritable* NewInstance();
  33.         ~Uninheritable();
  34. private:
  35.         Uninheritable();
  36. };
  37. */
  38. /*
  39. Accepts any acceptable index, or 0, and sets the stack top to this index. If the new top is larger the old  one, then the new elements are filled with nil. If index is 0, then all stack elements are removed.
  40. void lua_settop (lua_State *L, int index);
  41. --补充说明:设置index位置为栈顶。如果原先的栈顶大于index,则大于index的部分被清空,只保留小于等于index的部分。
  42. */
  43. void Error(lua_State* L, const char* fmt, ...){
  44.         va_list argp;
  45.         va_start(argp, fmt);
  46.         vfprintf(stderr, fmt, argp);
  47.         va_end(argp);
  48.         if(0 != L){
  49.                 lua_close(L);
  50.                 L = 0;
  51.         }
  52.         exit(EXIT_FAILURE);
  53. }
  54. bool Load(const char* filename, int* width, int*height){
  55.         lua_State* L = luaL_newstate();
  56.         if(0 == L){
  57.                 return false;
  58.         }
  59.         // luaL_openlibs(L);
  60.         if(luaL_loadfile(L, filename) || lua_pcall(L, 0, 0, 0)){
  61.                 Error(L, "Cannot run configuration file: %s", \
  62.                         lua_tostring(L, -1));
  63.         }
  64.         lua_getglobal(L, "width");
  65.         lua_getglobal(L, "height");
  66.         if(!lua_isnumber(L, -2)){
  67.                 Error(L, "'width' should be a number \n");
  68.         }
  69.         if(!lua_isnumber(L, -1)){
  70.                 Error(L, "'height' should be a number \n");
  71.         }
  72.         *width = (int)lua_tonumber(L, -2);
  73.         *height = (int)lua_tonumber(L, -1);
  74.         lua_close(L);
  75.         return true;
  76. }
  77. /*example_2*/
  78. int main(int argc, char* argv[]){
  79.         if(2 > argc){
  80.                 return -1;
  81.         }
  82.         int width(0), height(0);
  83.         if(Load(argv[1], &width, &height)){
  84.                 std::cout << "width = \t" << width << "\n";
  85.                 std::cout << "height = \t" << height << "\n";
  86.         }
  87.         return 0;
  88. }
  89. /*
  90. --filename : configuration.lua
  91. --configuration file for LuaTest appliation
  92. horizontal = true
  93. if horizontal then
  94.         width = 1024
  95.         height = 768
  96. else
  97.         width = 768
  98.         height = 1024
  99. end
  100. 命令行运行LuaTest控制台程序: LuaTest.exe configuration.lua
  101. */
  102. /*
  103. Push onto the stack the value of global name. It is defined as macro:
  104.         #define lua_getglobal(L, s) lua_getfield(L, LUA_GLOBALSINDEX, s)
  105. void lua_getglobal (lua_State *L, const char *name);
  106. Pushes onto the stack the value t[k], where t is the value at given valid index.
  107. void lua_getfield (lua_State *L, int index, const char *k);
  108. */
  109. /*sample_3*/
  110. #include <iostream>
  111. #include <string.h>
  112. #include <lua.hpp>
  113. void Error(lua_State* L, const char* fmt, ...){
  114.         va_list argp;
  115.         va_start(argp, fmt);
  116.         vfprintf(stderr, fmt, argp);
  117.         va_end(argp);
  118.         if(0 != L){
  119.                 lua_close(L);
  120.                 L = 0;
  121.         }
  122.         exit(EXIT_FAILURE);
  123. }
  124. const int MAX_COLOR = 255;
  125. /*Assume that table is on the stack top*/
  126. int GetField(lua_State* L, const char* key){
  127.         int res;
  128.         lua_pushstring(L, key);
  129.         lua_gettable(L, -2); /*get background[key]*/
  130.         if(!lua_isnumber(L, -1)){
  131.                 Error(L, "invalid component in background color.");
  132.         }
  133.         res = (int)(lua_tonumber(L, -1) * MAX_COLOR);
  134.         lua_pop(L, 1);       
  135.         return res;
  136. }
  137. struct ColorRGB{
  138.         unsigned char red, green, blue;
  139. };
  140. bool GetBackgroundColor(const char* filename, ColorRGB& rgb){       
  141.         lua_State* L = luaL_newstate();
  142.         if(0 == L){
  143.                 return false;
  144.         }
  145.         if(luaL_loadfile(L, filename) || lua_pcall(L, 0, 0, 0)){
  146.                 Error(L, "Cannot run configuration file : %s ", lua_tostring(L, -1));
  147.         }
  148.         /*push 全局变量background 到 stack.*/
  149.         lua_getglobal(L, "background");
  150.         if(!lua_istable(L, -1)){
  151.                 Error(L, "'background' is not a valid color table!");
  152.         }
  153.         rgb.red = GetField(L, "r");
  154.         rgb.green = GetField(L, "g");
  155.         rgb.blue = GetField(L, "b");
  156.         lua_close(L);
  157.         return true;
  158. }
  159. int main(int argc, char* argv[]){
  160.         if(2 > argc){
  161.                 return -1;
  162.         }
  163.         ColorRGB backgroundColor= {0, 0, 0};
  164.         if(GetBackgroundColor(argv[1], backgroundColor)){
  165.                 std::cout << "Red \t" << (int)backgroundColor.red << "\n";
  166.                 std::cout << "Green \t" << (int)backgroundColor.green << "\n";
  167.                 std::cout << "Blue \t" << (int)backgroundColor.blue << "\n";
  168.         }
  169.         return 0;
  170. }
  171. /*
  172. Pushes onto the stack the value t[k], where t is the value at the given valid index and k is the value at the top of the stack.
  173. 把t[k]入栈,t是栈中的一个table,由index来指定,k是栈顶的值。从命名可知t代表table,k代表key, t[k]代表value.
  174. This function pops the key from the stack (putting the resulting value in its place).
  175. 弹出将原先在栈顶的key,代之以value,即table[key]
  176. void lua_gettable (lua_State *L, int index);
  177. */
  178. /*
  179. Does the equivalent to t[k] = v, where t is the value at the given valid index, v is the value at the top of the stack, and k is the value just below the top.
  180. 这条语句的作用相当于table[key] = value, index 指定了table在栈中的位置。value是栈顶元素,key是栈顶元素的下一个元素。
  181. This function pops both the key and the value from the stack.
  182. 赋值结束后,value和key将被弹出栈。
  183. void lua_settable (lua_State *L, int index);
  184. */
  185. /*
  186. Pops n elements from the stack.
  187. 从栈中弹出n个元素
  188. void lua_pop (lua_State *L, int n);
  189. */
  190. /*
  191. 从stack中弹出一个值,并将这个值命名为 name。
  192. Pops a value from the stack and sets it as the new value of global name.
  193. void lua_setglobal (lua_State *L, const char *name);
  194. */
  195. /*
  196. Loads a Lua chunk (without running it). If there are no errors, lua_load pushes the compiled chunk as a Lua function on top of the stack. Otherwise, it push an error message.
  197. The return values of lua_load are:
  198.         LUA_OK: no error
  199.         ...
  200. int lua_load (lua_State *L,
  201.               lua_Reader reader,
  202.               void *data,
  203.               const char *source,
  204.               const char *mode);
  205. */
复制代码
作者:Wu_Xiangwei 发表于2012-1-16 19:36:57 原文链接


您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-5-3 06:13 , Processed in 0.056889 second(s), 7 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表