Lua 輕量(核心 < 200KB)、快速(基於寄存器的 VM)、易嵌入(純 C API)、動態類型、自動記憶體管理,是遊戲邏輯、配置腳本、插件系統的首選。本文系統梳理 Lua 5.1 C API 核心機制,提供 7 個完整 Demo,涵蓋雙向調用全場景。
Lua 與 C++ 所有數據交換通過虛擬棧進行:
lua_State 獨立擁有棧,線程不安全| API | 作用 | 棧變化 |
|---|---|---|
luaL_dofile(L, filename) | 載入並執行 Lua 檔案 | 0 → 0(正常)或 1(錯誤訊息) |
lua_getglobal(L, name) | 將全域變數壓棧 | 0 → 1 |
lua_setglobal(L, name) | 彈出棧頂設為全域變數 | 1 → 0 |
lua_pcall(L, nargs, nresults, errfunc) | 保護模式調用函數 | nargs+1 → nresults |
lua_pushinteger/number/string | 壓入基本類型 | 0 → 1 |
lua_tointeger/number/string | 從指定索引轉換取值 | 不改變棧 |
lua_gettable(L, idx) | 以棧頂為 key,idx 表查值 | 1 → 1(key 彈出,值壓入) |
lua_settable(L, idx) | idx 表中 key=value(棧頂 value,次頂 key) | 2 → 0 |
lua_next(L, idx) | 遍歷表:彈 key,壓 key-value 對 | 1 → 2(無下一對則 0→0) |
getLuaGlobalString 展示標準流程:lua_open → luaL_openlibs → luaL_dofile → lua_getglobal → lua_tostring → lua_close。注意 lua_settop(L,0) 清空棧確保乾淨環境。
getLuaVarOfTable 關鍵步驟:lua_getglobal 取表 → lua_pushstring 壓 key → lua_gettable(L, -2) 查值(-2 為表索引)。錯誤處理用 lua_istable 驗證。
getLuaVarTable 使用 lua_pushnil + lua_next 迭代。注意 lua_next 每次迭代後需 lua_pop(L,1) 移除 value 保留 key 供下輪。結果拼接用 memcpy 需手動管理緩衝區,實際項目建議用 std::string 或 std::vector。
標準協議:lua_getglobal 取函數 → 依序 lua_push* 參數 → lua_call(L, nargs, nresults) → 返回值在棧頂。Demo 中 lua_call(L,2,1) 對應 getIntegerSumFuncs(a,b) 兩參一回傳。
average 函數簽名固定為 int (*)(lua_State*)。步驟:lua_register(L, "average", average) 相當於 lua_pushcfunction → lua_setglobal。函數內部:lua_gettop 取參數數 → 迴圈 lua_tonumber 累加 → lua_pushnumber 壓回傳值 → return 回傳值個數。
所有 API 均可失敗,生產代碼必須檢查返回值:luaL_dofile 非 0 表示錯誤,錯誤訊息在棧頂;lua_pcall 非 0 表示運行錯誤;類型轉換前用 lua_isnumber/lua_isstring 驗證。
average 返回平均值與總和(return 2),Lua 端用 avg, sum = average(...) 接收。C++ 端調用後連續 lua_tointeger(L, -2), lua_tointeger(L, -1) 取值。
lua_State 需配對 lua_closeluaL_Buffer 或 userdata 避免頻繁字串拷貝lightuserdata + __gc 元方法lua_State 避免重複初始化開銷lua_rawgeti/lua_rawseti 繞過元表lua_createtable 預分配陣列/哈希部分lua_gettop 或用 RAII 包裝器lua_tostring 返回指針指向 Lua 內部緩衝區,需即時拷貝lua_State,跨線程傳值需序列化掌握「棧機制 + 核心 API + 錯誤處理」三要素,即可自信地在 C++ 專案中嵌入 Lua。建議從 Demo 1/4/5 入手,跑通「C++→Lua→C++」閉環,再按需擴展表操作、用戶數據、協程等高階特性。Lua 官方手冊《Programming in Lua》第 4 版第 24-30 章是權威參考。