lua中常常加載一些模塊來實現某些功能。如果沒有現成的模塊以供require,那麼我們只好自己寫模塊了。
前幾天用C給lua擴展了sha1算法模塊。提煉出來做個筆記。
lua示例代碼如下:
require "libencode" local str = "source str" local des = libencode.sha1(str) print(des)
我需要用libencode模塊中的sha1()函數求出des。很簡單,require該模塊,然後直接調用。那麼,這個庫怎麼來的呢?
分為三步:首先用C寫模塊(遵循規則),再把源碼編譯成動態庫,最後把動態庫拷貝到相應目錄下(必須是lua識別的目錄)
先貼出代碼:
#include <lua.h> #include <lauxlib.h> #include <lualib.h> static void encode_sha(const char* src, char* des) { /* *sha-hash //hash算法 */ } static int l_sha1(lua_State* lua) { const char *src = NULL; char des[40] = {0}; src = luaL_checkstring(lua, 1); //出棧獲取源字符串 encode_sha(src, des); //something lua_pushstring(lua, des); //壓棧返回給lua return 1; //告訴lua返回了一個變量 } //映射表,"sha1"為lua中的函數名,l_sha1為真正C中的函數地址 static const struct luaL_Reg encode[] = { {"sha1", l_sha1}, {NULL, NULL}, }; //模塊注冊函數 int luaopen_libencode(lua_State* lua) { //注冊本模塊中所有的功能函數,libencode為模塊名,encode數組存儲所有函數的映射關系 luaL_register(lua, "libencode", encode); return 1; }
encode[]數組中存儲lua中各個函數名和函數實際地址。
luaopen_xxx()函數負責注冊模塊。例如這裡當lua執行require "libencode"指令時便會搜尋luaopen_libencode()函數注冊模塊。
luaL_register()函數用給定名稱創建一個table。並用數組內容填充table。也就是說這個函數把模塊裡所有的API函數注冊到這個模塊名下,這樣就可以以(module.fun)這種格式在lua中訪問C函數了。
編譯:
gcc source.c -fPIC -shared -o source.so(如果lua時調用出錯,根據情況加其他編譯參數)
拷貝:
mv .../source.so LUA_C_PATH(這裡要拷貝到lua的c模塊路徑,命令行下執行print("C path:", package.cpath)獲得路徑)