專案需要 Lua 腳本支援,但引入 LuaBind + Boost 過於重型。決定按需實現輕量級封裝庫,支援:任意 C++ 函數註冊、Lua 函數調用、Lua 表/物件訪問、C++ 類綁定。
call_luaFunction<Ret>(name, L, args...):類型安全調用 Lua 函數register_function(L, name, func):註冊任意簽名 C++ 函數register_class<T>(L, name) + register_property + register_member_function:C++ 類綁定luaObject:代表 Lua 物件,支援 CallMemberFunction、Get/SetMemberValueluatable:代表 Lua 表,支援索引訪問、迭代Integer64:Lua 5.1 無 64 位整數,提供模擬類型luaWrapper lw; lw.init(); lw.load("start.lua");
lua_State *L = *(&lw);
register_function(L, "show", showmsg); // 註冊自由函數
register_class<testb>(L, "testb"); // 註冊類
register_property("valb", &testb::valb);
register_property("vald", &testb::vald);
register_member_function("func", &testb::function);
register_class<testc, testb>(L, "testc"); // 繼承綁定
register_member_function("funcc", &testc::functionc);
testc tc; tc.valb = 1000000000000000002LL;
call_luaFunction<void>("test1", L, &tc, 1000000000000000001LL);
luatable ret = call_luaFunction<luatable>("test2", L); // 獲取表
luaObject ac = call_luaFunction<luaObject>("test3", L); // 獲取物件
ac.CallMemberFunction<void>("show");
ac.SetMemberValue<int>("balance", 1000);
Account = { balance = 10, names = 0 }
function Account:withdraw(v) self.balance = self.balance - v end
function Account:new(o) o = o or {}; setmetatable(o, self); self.__index = self; return o end
function Account:show() print("this is account show") end
function Account:getBalance() return self.balance end
function Account:setBalance(val) self.balance = val end
function test1(tb, i) tb:func(); show("hello world"); print(tb.valb); tb.valb = i64:new(10000003); tb.vald = 1000.2; print(i) end
function test2() return {1,2,3,4,5} end
function test3() account = Account:new(); account.balance = 100; account.name = "sniperHW"; return account end
function test4() return 1,2,3,4,5 end
function test5(lt) for i=1,5 do print(lt[i]) end end
function test6(str) print(str) end
lua_results<N>)、64位整數、STL 容器雙向轉換此封裝庫在實際專案中穩定運行多年,證明了「按需構建、輕量足夠」的工程哲學。