稍微針對 C# 做了修改如下:
protected bool load_file_into_namespace(IntPtr L, string S, string N, bool bCall) { lua_pushlstring(L, N, N.Length); lua_gettable(L, (-10002)); if (lua_isnil(L, -1)) { lua_pop(L, 1); lua_newtable(L); lua_pushlstring(L, N, N.Length); lua_pushvalue(L, -2); lua_settable(L, (-10002)); } else { if (!lua_istable(L, -1)) { lua_pop(L, 1); return (false); } } lua_newtable(L); lua_pushlstring(L, "_G", 2); lua_gettable(L, (-10002)); lua_pushnil(L); while (lua_next(L, -2) != 0) { lua_pushvalue(L, -2); lua_pushvalue(L, -2); lua_settable(L, -6); lua_pop(L, 1); } if ((luaL_loadfile(L, S) > 0)) { Console.Write("Error in file " + S + "!\n"); for (int i = 0; ; i++) if ((lua_isstring(L, i) > 0)) { Console.Write(lua_tolstring(L, i, IntPtr.Zero) + "\n"); } else break; lua_error(L); lua_pop(L, 3); return (false); } if (bCall) lua_call(L, 0, 0); else lua_insert(L, -4); lua_pushnil(L); while (lua_next(L, -2) != 0) { lua_pushvalue(L, -2); lua_gettable(L, -5); if (lua_isnil(L, -1)) { lua_pop(L, 1); lua_pushvalue(L, -2); lua_pushvalue(L, -2); lua_pushvalue(L, -2); lua_pushnil(L); lua_settable(L, -7); lua_settable(L, -7); } else { lua_pop(L, 1); lua_pushvalue(L, -2); lua_gettable(L, -4); if (!(lua_equal(L, -1, -2) > 0)) { lua_pushvalue(L, -3); lua_pushvalue(L, -2); lua_pushvalue(L, -2); lua_pushvalue(L, -5); lua_settable(L, -8); lua_settable(L, -8); } lua_pop(L, 1); } lua_pushvalue(L, -2); lua_pushnil(L); lua_settable(L, -6); lua_pop(L, 1); } lua_pop(L, 3); return (true); }
其中 S 表示檔案路徑, N 表示名稱空間。呼叫名稱空間內的 function 方式也會有些不同:
1) 以 luaL_dostring 方式呼叫:
假設載入的file0.lua 檔如下:
function pp() print("this is file0"); end
載入的 file1.lua 檔案下:
function pp() print("this is file1"); end
載入 file0.lua 時設定的 namespace 為 A0,載入 file1.lua 時設定的 namespace 為 A1,載入的程式碼為:
load_file_into_namespace(m_luaState, "file0.lua", "A0", true); load_file_into_namespace(m_luaState, "file1.lua", "A1", true);
則分別呼叫 file0.lua及file1.lua內的 pp() 函數方式如下:
A0.pp(); A1.pp();
程式碼寫法是:
luaL_dostring(m_luaState, "A0.pp()"); luaL_dostring(m_luaState, "A1.pp()");
2) 以 lua_pcall 方式呼叫(以呼叫 A0.pp() 為例子)
lua_getglobal(m_luaState, "A0"); if (lua_type(m_luaState, -1) == 5) { lua_getfield(m_luaState, -1, "pp"); if (lua_type(m_luaState, -1) == 6) { // This removes the foo table from the stack lua_replace(m_luaState, -2); ret = lua_pcall(m_luaState, 0, 0, 0); if (ret != 0) { lua_pop(m_luaState, 1); } } else { lua_pop(m_luaState, 2); } } else { lua_pop(m_luaState, 1); }
0 意見 :
張貼留言