1. 程式人生 > >用C C++ 編寫lua模塊的一般模式

用C C++ 編寫lua模塊的一般模式

方式 調用函數 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模塊的一般模式