Lua 與 C 互調入門:Ubuntu 下編譯實戰,從 C 調用 Lua 到 Lua 調用 C 全流程
環境準備
sudo apt-get install lua5.1 lua5.1-0-dev
ln -s /usr/bin/lua5.1 /usr/bin/lua # 方便直接輸入 lua
lua -v # Lua 5.1.x
場景一:C 調用 Lua 腳本
add.lua
function add(a, b)
return a + b
end
add.c
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main() {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
if (luaL_dofile(L, "add.lua")) {
fprintf(stderr, "Error: %s\n", lua_tostring(L, -1));
return 1;
}
lua_getglobal(L, "add");
lua_pushnumber(L, 10);
lua_pushnumber(L, 20);
lua_call(L, 2, 1); // 2參數,1返回值
printf("Result: %d\n", (int)lua_tonumber(L, -1));
lua_close(L);
return 0;
}
編譯運行
gcc -o add add.c -I /usr/include/lua5.1 -llua5.1
./add # 輸出 Result: 30
場景二:Lua 調用 C 動態庫
power_lua.c
#include <lua.h>
#include <lauxlib.h>
#include <math.h>
static int l_pow(lua_State *L) {
double base = luaL_checknumber(L, 1);
double exp = luaL_checknumber(L, 2);
lua_pushnumber(L, pow(base, exp));
return 1;
}
static const luaL_Reg mylib[] = {
{"pow", l_pow},
{NULL, NULL}
};
int luaopen_power(lua_State *L) {
luaL_newlib(L, mylib);
return 1;
}
編譯為 .so
gcc -Wall -shared -fPIC -o power.so -I/usr/include/lua5.1 power_lua.c
hello.lua
local power = require "power"
print("2^10 = " .. power.pow(2, 10))
運行
lua hello.lua
# 輸出 2^10 = 1024
關鍵點總結
| 方向 | 核心 API | 產物 | 編譯關鍵 |
| C → Lua | luaL_dofile, lua_getglobal, lua_call | 可執行文件 | -I/usr/include/lua5.1 -llua5.1 |
| Lua → C | luaL_Reg, luaL_newlib, luaopen_XXX | .so 動態庫 | -shared -fPIC -o power.so |
常見坑點
- 頭文件路徑:Ubuntu 下在
/usr/include/lua5.1,需 -I 指定;
- 庫文件名:
-llua5.1 對應 liblua5.1.so;
.so 放置:與調用腳本同目錄,或設置 LUA_CPATH / package.cpath;
- 棧平衡:每次
lua_call / C 函數返回前確保棧頂只留返回值,否則洩漏/崩潰。