Lua與C的基礎互動
阿新 • • 發佈:2018-11-02
// // testLua.cpp // testLuaCall // // Created by ljw on 2018/9/26. // Copyright © 2018年 x. All rights reserved. // #pragma once #include "lua/lua.h" #include "lua/lualib.h" #include "lua/lauxlib.h" #include "lua_bridge.h" /* #define LUA_TNIL 0 #define LUA_TBOOLEAN 1 #define LUA_TLIGHTUSERDATA 2 #define LUA_TNUMBER 3 #define LUA_TSTRING 4 #define LUA_TTABLE 5 #define LUA_TFUNCTION 6 #define LUA_TUSERDATA 7 #define LUA_TTHREAD 8 */ void dump(lua_State* L) { int top = lua_gettop(L); int type = LUA_TNONE; char typestr[20]; for (int i = top; i != 0; i--) { type = lua_type(L, i); // 獲取type switch (type) { case LUA_TNIL: snprintf(typestr, 20, "nil"); break; case LUA_TBOOLEAN: snprintf(typestr, 20, "boolean"); break; case LUA_TLIGHTUSERDATA: snprintf(typestr, 20, "light-userdata"); break; case LUA_TNUMBER: snprintf(typestr, 20, "number"); break; case LUA_TSTRING: snprintf(typestr, 20, "string"); break; case LUA_TTABLE: snprintf(typestr, 20, "table"); break; case LUA_TFUNCTION: snprintf(typestr, 20, "function"); break; case LUA_TUSERDATA: snprintf(typestr, 20, "userdta"); break; case LUA_TTHREAD: snprintf(typestr, 20, "thread"); break; default: snprintf(typestr, 20, "unknow"); break; break; } printf("[Stack Index:%d]%s\t: %s \n", i, typestr, lua_tostring(L, i)); } } void clearStack(lua_State* L) { lua_pop(L, lua_gettop(L)); } void doPushStack(lua_State* L) { clearStack(L); lua_pushstring(L, "this is test string in stack 1");//棧index = 1 lua_pushnumber(L, 1); // 棧index = 2 lua_pushboolean(L, 1); // 棧index = 3 lua_pop(L, 1); // 從棧頂(最大棧Index)推出一個元素 dump(L); clearStack(L); dump(L); } void doAdd(lua_State* L) { clearStack(L); if (luaL_dostring(L, "add = function(x, y) return x + y end")) { return; } lua_getglobal(L, "add"); //棧Index = 1 dump(L); lua_pushnumber(L, 1); //棧Index = 2 lua_pushnumber(L, 2); //棧Index = 3 //lua_pushnumber(L, 3); //引數個數異常測試 dump(L); lua_pcall(L, 2, 1, 0); //pcall 為執行棧Index 為 1 的方法 第二個引數為z傳入 n 個引數 第三個引數為返回 n 個引數 執行完成之後將pop出 (1(方法棧) + 所有引數個數)個棧內元素 並將返回值入棧 如果引數個數不正確 將返回attempt to call a string value dump(L); clearStack(L); } void doDumpTableSimple(lua_State* L) { clearStack(L); if (luaL_dostring(L, "testTable = { a = 123, b = 456 , c = 'ccc'}")) { return; } lua_getglobal(L, "testTable"); int idx = lua_gettop(L); printf("%d\n", idx); lua_pushnil(L); while (1) { if (!lua_next(L, idx)) break; //dump(L); printf("[key]:%s, [value]:%s\n", lua_tostring(L, -1), lua_tostring(L, -2)); lua_pop(L, 1); //dump(L); } //dump(L); } void doGetTableValue(lua_State* L) { clearStack(L); if (luaL_dostring(L, "testTable = { a = 123, b = 456 , c = 'ccc'}")) { return; } lua_getglobal(L, "testTable"); //棧Index 1 lua_pushstring(L, "a"); //棧Index 2 lua_pushstring(L, "b"); //棧Index 3 lua_pushstring(L, "c"); //棧Index 4 dump(L); lua_gettable(L, 1); //GetTable方法 在棧尾為table的情況下 獲取棧頂所在元素為Key值的元素 並替換該Key元素為Table對應的Value dump(L); } int cMethod(lua_State* L) { int i = 0; int sum = 0; //檢索所有的number值 int NOS = lua_gettop(L); while (++i <= NOS) { if (lua_isnumber(L, i)) sum += lua_tointeger(L, i); else printf("Index %d is not a number!\n", i); } clearStack(L); //清除棧 lua_pushnumber(L, sum); //返回值 return 1; } void doCallCMethod(lua_State* L) { clearStack(L); lua_register(L, "cMethod", cMethod); if (luaL_dostring(L, "print(cMethod(1, 2, 3, 4, 5, saf) or 'failed')")) { return; } dump(L); } void testLuaStack(lua_State* L) { clearStack(L); for (int i = 0; i != 10; ++i) { lua_pushnumber(L, i); } dump(L); printf("%d\n", lua_tointeger(L, 1)); //1 printf("%d\n", lua_tointeger(L, 2)); //2 printf("%d\n", lua_tointeger(L, 3)); //3 printf("%d\n", lua_tointeger(L, -1)); //10 printf("%d\n", lua_tointeger(L, -2)); //9 printf("%d\n", lua_tointeger(L, -3)); //8 /* * 總結 元素入棧時 所有已入棧的元素Index + 1 * Indexu最大的為h棧頂 * 獲取的傳入Index為正數時, 順序為棧頂-棧尾 10-1 * 獲取的傳入Index為負數時,順序為棧尾-棧頂 1-10 * */ } void doTest(lua_State* L) { //doPushStack(L); //doAdd(L); //doGetTableValue(L); //doDumpTableSimple(L); //doCallCMethod(L); testLuaStack(L); }