用C C++ 編寫lua模塊的一般模式
阿新 • • 發佈:2018-03-08
方式 調用函數 oid pan 字符串 api [] ber pack
作為一種嵌入式語言,lua提供了一套完備的 C API來幫助 lua 與 宿主程序進行交互。因此使用 C 或者 C++ 來為lua編寫模塊是很容易的。
看一下lua (5.1) 中對 string 模塊的封裝源碼 lstrlib.c
在 lstrlib.c 最後有這樣的代碼
/**
將函數名與實際調用函數記錄在一個 struct 中,並組成一個數組
--- 有點 lua 代碼的趕腳 ---
**/
static const luaL_Reg strlib[] = {
{"byte", str_byte},
{"char", str_char},
{"dump", str_dump},
{"find" , str_find},
{"format", str_format},
{"gmatch", gmatch},
{"gsub", str_gsub},
{"len", str_len},
{"lower", str_lower},
{"match", str_match},
{"rep", str_rep},
{"reverse", str_reverse},
{"sub", str_sub},
{"upper", str_upper},
{"pack", str_pack},
{"packsize", str_packsize},
{"unpack" , str_unpack},
{NULL, NULL}
};
/**
這裏是對創建的lib 元表進行後續加工,具體可以看源代碼
**/
static void createmetatable (lua_State *L) {
....
}
/*
** Open string library
** 這裏是string 庫的主入口
*/
LUAMOD_API int luaopen_string (lua_State *L) {
luaL_newlib(L, strlib); // 創建一個 lib 元表,並將 strlib 5.2之前使用luaL_register(L, "modulename", modulename); 中的函數名與函數放到表中
createmetatable(L); // 對創建的 lib 元表進行再次處理
return 1;
}
類似的代碼也出現再了 loadlib.c(package模塊)、loslib.c(os 模塊)
因此可以總結出 lua 模塊的編寫方式
- 1、定義 C/C++ 中的 函數
- 2、定義 luaL_Reg 數組
- 3、創建 lib 元表。這裏需要註意 在 5.2 之後的版本中可以直接使用 luaL_newlib,而之前的版本需要使用 luaL_register(L, "modulename", modulename);
C/C++ 與 lua 類型
將數據傳入lua接口
/**
向棧中壓入 NULL
**/
LUA_API void (lua_pushnil) (lua_State *L);
/**
向棧中壓入 double
**/
LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
/**
向棧
**/
LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
/**
將字符串s的指定長度len壓入棧中
**/
LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
/**
向棧中壓入一個字符串
**/
LUA_API void (lua_pushstring) (lua_State *L, const char *s);
/**
向棧中壓入字符串並格式化
**/
LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
va_list argp);
/**
向棧中壓入字符串並格式化
使用可變參數進行格式化
**/
LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
/**
向棧中壓入一個C函數
**/
LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
/**
將 b 作為布爾值壓入棧中
**/
LUA_API void (lua_pushboolean) (lua_State *L, int b);
/**
將一個輕量用戶數據壓入棧中
**/
LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
/**
"L"表示的線程入棧。如果這個線程是當前狀態機的主線程的話,返回1。
**/
LUA_API int (lua_pushthread) (lua_State *L);
用C C++ 編寫lua模塊的一般模式