LuaTest.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. // LuaTest.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include "LuaTest.h"
  5. extern "C" {
  6. #include "lua.h"
  7. #include "lualib.h"
  8. #include "lauxlib.h"
  9. }
  10. #include "Lua51.h"
  11. #include "Lua53.h"
  12. #ifdef _DEBUG
  13. #define new DEBUG_NEW
  14. #endif
  15. // 唯一的应用程序对象
  16. CWinApp theApp;
  17. using namespace std;
  18. //////////////////////////////////////////////////////////////////////////
  19. int l_TestFunction(lua_State *luaVM);
  20. int RunLua(const char* pScript, const int nlen);
  21. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  22. {
  23. int nRetCode = 0;
  24. // 初始化 MFC 并在失败时显示错误
  25. if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
  26. {
  27. // TODO: 更改错误代码以符合您的需要
  28. _tprintf(_T("错误: MFC 初始化失败\n"));
  29. nRetCode = 1;
  30. }
  31. else
  32. {
  33. Lua51 lua51;
  34. lua_State *pVM = lua51.Open("lua5.1.lua");
  35. lua51.CallLuaTableVariable(pVM, "tb_User");
  36. lua_close(pVM);
  37. // TODO: 在此处为应用程序的行为编写代码。
  38. #if 1 // 基本操作;
  39. // 创建lua对象;
  40. lua_State *luaVM = luaL_newstate();
  41. // 加载所有lua支持的lib;
  42. luaL_openlibs(luaVM);
  43. // 加载脚本文件;
  44. luaL_dofile(luaVM, "main.lua");
  45. // 获取全局变量,压栈索引从-1开始;
  46. lua_getglobal(luaVM, "nWidth");
  47. lua_getglobal(luaVM, "nHeight");
  48. // 注意,number在lua中表示的是浮点数;
  49. // 只有在更高版本的lua中, 才有integer;
  50. if (lua_isnumber(luaVM, -1))
  51. {
  52. printf("nWidth=%f\n", lua_tonumber(luaVM, -1));
  53. }
  54. if (lua_isnumber(luaVM, -2)) // lua_isinteger 在 lua5.3中才有;
  55. {
  56. printf("nHeight=%f\n", lua_tonumber(luaVM, -2));
  57. }
  58. // 恢复lua的栈;
  59. lua_pop(luaVM, 1);
  60. // 加载字符串脚本;
  61. luaL_dostring(luaVM, "print(100);");
  62. // 关闭lua;
  63. lua_close(luaVM);
  64. #endif
  65. }
  66. #if 0 // lua调用vc里的函数;
  67. const char* pScript = "TestFunction(true, 1,\"运行lua,这是lua中的函数, 调用程序中的函数来处理\");";
  68. RunLua(pScript, strlen(pScript));
  69. #endif
  70. #if 0 // vc调用lua里的函数;
  71. // 创建lua对象;
  72. lua_State *luaVM = luaL_newstate();
  73. // 加载所有lua支持的lib;
  74. luaL_openlibs(luaVM);
  75. // 加载脚本文件;
  76. luaL_dofile(luaVM, "m2.lua");
  77. // 取到一个全局标号add,取的同时会把add函数压栈;
  78. lua_getglobal(luaVM, "add");
  79. // 把两个函数所需要的参数压入栈里;
  80. lua_pushnumber(luaVM, 100);
  81. lua_pushnumber(luaVM, 200);
  82. // 执行lua中的脚本;
  83. if (lua_pcall(luaVM, 2/*参数个数*/, 1/*返回值个数*/, 0) != 0)
  84. {
  85. printf("error run lua %s\n", lua_tostring(luaVM, -1));
  86. // 将错误消息占用内存从栈中弹出;
  87. lua_pop(luaVM, 1);/* pop error message from the stack */
  88. }
  89. // 函数执行完了,执行结果被压栈,所以取得最顶端的一个数就是结果值,-1就是指取栈顶的值;
  90. // 检查返回值类型;
  91. if (lua_isnumber(luaVM, -1))
  92. {
  93. int nRet = (int)lua_tonumber(luaVM, -1);
  94. printf("vc调用lua中的函数, 返回值: %d\n", nRet);
  95. }
  96. // 将lua函数返回值出栈;
  97. lua_pop(luaVM, 1);
  98. // 关闭lua;
  99. lua_close(luaVM);
  100. #endif
  101. #if 0 // lua调用vc里的函数的另一种实现方式;
  102. // 创建lua对象;
  103. lua_State *luaVM = luaL_newstate();
  104. // 加载所有lua支持的lib;
  105. luaL_openlibs(luaVM);
  106. // 将vc函数指针压入栈;<不仅只有纯C函数才可以, VC函数也可以>
  107. // 首先,将函数名入栈;
  108. lua_pushstring(luaVM, "TestFunction");
  109. // 其次,将函数指针入栈;
  110. lua_pushcfunction(luaVM, l_TestFunction);
  111. // 最后,调用lua_settable注册函数;
  112. // lua中定义的变量和函数存放在一个全局table中,索引值为LUA_GLOBALSINDEX,table相关操作接口:
  113. lua_settable(luaVM, LUA_GLOBALSINDEX);
  114. // 加载脚本文本;
  115. luaL_dostring(luaVM, "TestFunction(true, 1,\"运行lua,这是lua中的函数, 调用程序中的函数来处理\");");
  116. // 关闭lua环境;
  117. lua_close(luaVM);
  118. #endif
  119. // 等待退出;
  120. system("pause");
  121. return nRetCode;
  122. }
  123. /************************************************************************/
  124. /* 函数:[1/15/2018 Jeff];
  125. /* 描述:;
  126. /* 参数:;
  127. /* [IN] :;
  128. /* [OUT] :;
  129. /* [IN/OUT] :;
  130. /* 返回:void;
  131. /* 注意:;
  132. /* 示例:;
  133. /*
  134. /* 修改:;
  135. /* 日期:;
  136. /* 内容:;
  137. /************************************************************************/
  138. int l_TestFunction(lua_State *luaVM)
  139. {
  140. // 判断参数有效性;
  141. if (!lua_isboolean(luaVM, 1) || !lua_isnumber(luaVM, 2) || !lua_isstring(luaVM, 3))
  142. {
  143. return -1;
  144. }
  145. // 第一个参数;
  146. BOOL bVisible = lua_toboolean(luaVM, 1);
  147. // 获取第二个参数;
  148. int nIndex = (int)lua_tonumber(luaVM, 2);
  149. // 测试第三个参数是否为字串形式,并取得这个字串;//lua_tostring//luaL_checkstring
  150. // const char* pText = luaL_checkstring(luaVM, 3);
  151. const char* pText = lua_tostring(luaVM, 3);
  152. // 用户自定义处理;
  153. printf("lua函数返回: %s, %d, %s \n", bVisible ? "true" : "false", nIndex, pText);
  154. return 0;
  155. }
  156. /************************************************************************/
  157. /* 函数:[1/15/2018 Jeff];
  158. /* 描述:;
  159. /* 参数:;
  160. /* [IN] pScript:lua脚本;
  161. /* [IN] nlen:脚本长度;
  162. /* [IN/OUT] :;
  163. /* 返回:void;
  164. /* 注意:;
  165. /* 示例:;
  166. /*
  167. /* 修改:;
  168. /* 日期:;
  169. /* 内容:;
  170. /************************************************************************/
  171. int RunLua(const char* pScript, const int nlen)
  172. {
  173. // 参数校验;
  174. if (pScript == NULL || nlen == 0)
  175. return -1;
  176. // 打开lua,创建lua虚拟环境;
  177. #ifndef LUA53
  178. lua_State *luaVM = lua_open();
  179. #else
  180. lua_State *luaVM = luaL_newstate();
  181. #endif
  182. if (luaVM == NULL)
  183. return -1;
  184. // 为lua环境加载全部lib库;
  185. luaL_openlibs(luaVM);
  186. /* 也可以单独加载需要的库,而不用全部加载;
  187. luaopen_base(luaVM ); // opens the basic library.
  188. luaopen_table(luaVM ); // opens the table library.
  189. luaopen_io(luaVM ); // opens the I/O library.
  190. luaopen_string(luaVM ); // opens the string lib.
  191. luaopen_math(luaVM ); // opens the math lib.
  192. luaopen_debug (lua);
  193. */
  194. // 注册所有函数;
  195. lua_register(luaVM, "TestFunction", l_TestFunction);
  196. // luaL_loadbuffer 将脚本加载进lua环境中;
  197. // lua_pcall执行lua环境中的脚本;
  198. int nErr = luaL_loadbuffer(luaVM, pScript, nlen, "main") || lua_pcall(luaVM, 0, 0, 0);
  199. if (nErr)
  200. {
  201. printf("error run lua %s\n", lua_tostring(luaVM, -1));
  202. // 将错误消息占用内存从栈中弹出;
  203. lua_pop(luaVM, 1);/* pop error message from the stack */
  204. }
  205. // 关闭lua环境;
  206. lua_close(luaVM);
  207. return 0;
  208. }
  209. /************************************************************************/
  210. /* 函数:[1/15/2018 Jeff];
  211. /* 描述:;
  212. /* 参数:;
  213. /* [IN] :;
  214. /* [OUT] :;
  215. /* [IN/OUT] :;
  216. /* 返回:void;
  217. /* 注意:;
  218. /* 示例:;
  219. /*
  220. /* 修改:;
  221. /* 日期:;
  222. /* 内容:;
  223. /************************************************************************/
  224. int StackDump(lua_State* luaVM)
  225. {
  226. // 得到栈的元素个数,栈顶的位置;
  227. int nTop = lua_gettop(luaVM);
  228. // 输出栈顶位置;
  229. printf("The Length of stack is %d/n", nTop);
  230. for (int i = 1; i <= nTop; ++i)
  231. {
  232. int t = lua_type(luaVM, i);
  233. // 这里的typename是把类型的枚举变成字符串,是类型名,不是栈中的位置;
  234. printf("%s:", lua_typename(luaVM, t));
  235. switch (t)
  236. {
  237. case LUA_TNUMBER:
  238. printf("%f", lua_tonumber(luaVM, i));
  239. break;
  240. case LUA_TSTRING:
  241. printf("%s", lua_tostring(luaVM, i));
  242. break;
  243. case LUA_TTABLE:
  244. //printf("%s/n", lua_tostring(luaVM,i));
  245. break;
  246. case LUA_TFUNCTION:
  247. //printf("%s/n", lua_tostring(luaVM,i));
  248. break;
  249. case LUA_TNIL:
  250. printf("Is NULL");
  251. break;
  252. case LUA_TBOOLEAN:
  253. printf("%s", lua_toboolean(luaVM, i) ? "true" : "false");
  254. break;
  255. default:
  256. break;
  257. }
  258. printf("/n");
  259. }
  260. return 0;
  261. }