Lua:模組、使用位操作BitOp、C API(Lua與C互相呼叫)
一、模組
1.1 概述
建立一個模組最簡單的方法是:
1. 建立一個table;
2. 並將所有需要匯出的函式放入其中;
3. 最後返回這個table。
1.2 程式碼
檔案:test.lua
complex = {}
function complex.add(x, y)
return x+y
end
return complex
1.2 執行結果
載入模組:require (“test”)
二、使用位做操
1.1 Lua位操作
Lua不支援位操作,需要單獨下載位操作的模組BitOp。
1.2 下載、安裝位操作模組
下載:
檔名:LuaBitOp-1.0.2.tar.gz
安裝:
tar zxvf LuaBitOp-1.0.2.tar.gz
cd LuaBitOp-1.0.2
make (可能需要修改bit.c中包含的lua.h檔案的路徑)
make install
1.3 使用位操作
載入模組:require (“bit”)
三、Lua呼叫C函式
3.1 程式碼:將C函式寫成模組
#include <stdio.h> #include <string.h> #include "/root/LuaJIT-2.0.2/src/lua.h" #include "/root/LuaJIT-2.0.2/src/lauxlib.h" #include "/root/LuaJIT-2.0.2/src/lualib.h" static int c_add(lua_State* L) { //1. 檢查棧中的引數是否合法,1表示Lua呼叫時的第一個引數(從左到右),依次類推。 //1. 如果Lua程式碼在呼叫時傳遞的引數不為number,該函式報錯並終止程式執行。 double op1 = luaL_checknumber(L,1); double op2 = luaL_checknumber(L,2); //2. 將函式的結果壓入棧中。 //2. 如果有多個返回值,可以在這裡多次壓入棧。 lua_pushnumber(L,op1 + op2); //3. 返回值用於提示該C函式的返回值數量,即壓入棧中的返回值數量 return 1; } static const struct luaL_Reg test[] = { {"add", c_add}, {NULL, NULL} }; //宣告一個主函式 LUALIB_API int luaopen_test(lua_State* L) { luaL_register(L,"test",test); return 1; }
3.2 編譯
寫完C模組後,必須將其連結到直譯器。
必須將C程式碼編譯成動態連結庫。
將C程式碼編譯成動態庫:
gcc -fPIC -O2 -fomit-frame-pointer -Wall -I/usr/local/include -c -o test.o test.c
gcc -shared -fPIC -o test.so test.o
將動態庫拷貝到Lua的lib目錄下:
cp test.so /usr/lib64/lua/5.1/
3.3 Lua中呼叫C函式
和呼叫Lua模組中函式一樣:require ("test")
四、C呼叫Lua函式
4.1 程式碼
兩個公共:
lua作為配置檔案,被C讀取;
lua中有lua函式,被C呼叫執行。
配置檔案:data.lua
width = 200
height = 300
add = function (x, y)
return x + y
end
程式碼檔案:test.c
#include <stdio.h>
#include <stdlib.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
int add(lua_State *L, int x, int y)
{
lua_getglobal(L, "add");
lua_pushnumber(L, x);
lua_pushnumber(L, y);
if (lua_pcall(L, 2, 1, 0) != 0)
{
error(L, "error running function 'add':%s\n", lua_tostring(L, -1));
}
if (!lua_isnumber(L, -1))
{
error(L, "function 'add' must return a number.\n");
}
int z = lua_tonumber(L, -1);
lua_pop(L, 1);
return z;
}
int main(int argc, char*argv[])
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
//0. load lua config
if (luaL_loadfile(L, "/root/1103/data.lua") || lua_pcall(L, 0, 0, 0))
error(L, "cann't:%s", lua_tostring(L, -1));
//1. read lua variable
lua_getglobal(L, "width");
lua_getglobal(L, "height");
if (!lua_isnumber(L, -2))
error(L, "'width' should be a number.");
if (!lua_isnumber(L, -1))
error(L, "'height' should be a number.");
int w = lua_tointeger(L, -2);
int h = lua_tointeger(L, -1);
printf("width:%d, height:%d\n", w, h);
//2. read and run lua function
int sum = add(L, 10, 4);
printf("sum:%d\n", sum);
lua_close(L);
return 0;
}
4.2 編譯
gcc -o test test.c -I /usr/local/luajit/include/luajit-2.1 -L /usr/local/luajit/lib -l luajit-5.1
4.3 執行結果
參考資料: