【Lua】スタック
スタックを把握する為に以下ソースコードをメモする。
詳しいことは、以下参考URLから参照。
参考: その2 Luaスクリプト事始め
#include <iostream> #include <lua.hpp> // スタック確認 void printStack(lua_State* L) { // スタック数を取得 const int num = lua_gettop(L); if (num == 0) { printf("No stack.\n"); return; } for (int i = num; i >= 1; --i) { // インデックス番号(昇順・降順) printf("%03d(%04d):", i, -num + i - 1); // 型確認 int type = lua_type(L, i); switch (type) { case LUA_TNIL: printf("NIL\n"); break; case LUA_TBOOLEAN: printf("BOOLEAN %s\n", lua_toboolean(L, i) ? "true" : "false"); break; case LUA_TLIGHTUSERDATA: printf("LIGHTUSERDATA\n"); break; case LUA_TNUMBER: printf("NUMBER %f\n", lua_tonumber(L, i)); break; case LUA_TSTRING: printf("STRING %s\n", lua_tostring(L, i)); break; case LUA_TTABLE: printf("TABLE\n"); break; case LUA_TFUNCTION: printf("FUNCTION\n"); break; case LUA_TUSERDATA: printf("USERDATA\n"); break; case LUA_TTHREAD: printf("THREAD\n"); break; } } printf("------------------------------\n\n"); } // スタックを積んで表示する void testPrintStack() { lua_State *L = luaL_newstate(); // スタックする lua_pushboolean(L, 1); lua_pushnumber(L, 100.0); lua_pushstring(L, "test"); // スタックを表示する printStack(L); lua_close(L); } // Luaコードを読み込んで表示する void testInit() { lua_State* L = luaL_newstate(); // Luaファイルを開いて読み込み(失敗は0以外を返却) // ファイルが存在しないかLuaコードに間違いがある場合は失敗する if (luaL_dofile(L, "init.lua")) { // スタックからエラー文字列を表示 printf("%s\n", lua_tostring(L, lua_gettop(L))); lua_close(L); return; } // Luaステートに読み込まれたグローバル変数をスタックする // スタックできない場合は、NILがスタックされる lua_getglobal(L, "windowWidth"); lua_getglobal(L, "windowHeight"); lua_getglobal(L, "windowName"); // スタックを表示する printStack(L); // スタックを削除 int num = lua_gettop(L); lua_pop(L, num); printStack(L); // No Stack. lua_close(L); } // C言語からLuaの関数を呼ぶ void testLuaFunc() { lua_State* L = luaL_newstate(); // Luaファイルを読み込み if (luaL_dofile(L, "func.lua")) { printf("%s\n", lua_tostring(L, lua_gettop(L))); lua_close(L); return; } // Luaステート内にあるcalc関数をスタックする lua_getglobal(L, "calc"); // 引数をスタックする lua_pushnumber(L, 100); lua_pushnumber(L, 200); // 現時点でのスタックを確認する printStack(L); // Lua関数を実行して関数をスタックからポップさせ、 // 複数な戻り値をスタックさせる // int lua_pcall(arg1, arg2, arg3, arg4) 引数は以下を参照 // arg1: 関数が登録されているLuaステート // arg2: 関数の引数の数 // arg3: 関数の戻り値の数 // arg4: 独自のエラーメッセージを取り扱う時に使用、デフォルトは0 if (lua_pcall(L, 2, 4, 0)) { printf("%s\n", lua_tostring(L, lua_gettop(L))); lua_close(L); return; } // 実行後のスタックを確認する printStack(L); // 複数な戻り値を取得する float add = (float)lua_tonumber(L, 1); float sub = (float)lua_tonumber(L, 2); float mult = (float)lua_tonumber(L, 3); float dev = (float)lua_tonumber(L, 4); // 取得した値を表示する printf("add:%f sub:%f mult:%f dev:%f\n\n", add, sub, mult, dev); // スタックを削除する int num = lua_gettop(L); lua_pop(L, num); lua_close(L); } int main(int argc, char* argv[]) { //testPrintStack(); //testInit(); testLuaFunc(); return 0; }
以下は、読み込ませるLuaのコードとなる。
ファイルの拡張子は別に付けなくても可能である。
init.lua
windowWidth = 640 windowHeight = 480 windowName = "init"
func.lua
--複数の値を返却する function calc(val1, val2) return val1 + val2, val1 - val2, val1 * val2, val1 / val2 end