1. 程式人生 > >lua原始碼學習(一)lua的c api外圍實現

lua原始碼學習(一)lua的c api外圍實現

工作後,整個人已經比較鬆懈了。儘管一直在看lua的原始碼。可是一直是比較零碎的時間,沒有系統的整理,所以還是收穫不多。由於近期工作也不是非常忙了,就想整理下lua的原始碼學習的筆記。加深下印象,並分享給大家。

先說下這系列bolg我會每週更新2-3篇,沒有順序的

這些文章都是自己的淺薄的理解。有什麼錯誤,還請各位拍磚賜教。

1.關於c語言函式的宣告

相信大家都知道介面的重要,在lua中。假設要呼叫c語言的函式,就必需要有一個統一的函式宣告:

typedef int (*lua_CFunction) (lua_State *L);

可是,我們非常多函式都不是這種宣告。所以。我們就需要有一個包裝函式:

比方cos函式:

在c語言,標準math庫中,宣告例如以下:

double cos (double);

經過包裝後:

static int math_cos (lua_State *L) {
  lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
  return 1;
}

由於lua是一個狀態機。全部的操作都是在操作棧。所以lua_CFunction中傳入的lua_state這個棧,就能夠獲取lua執行中的全部資料了

luaL_checknumber(L,1):表示獲取棧頂的number,而且呼叫標準c的cos函式,而且cos計算值又一次壓棧。

2.關於luaL_Reg對映表

我們介面已經好了。那麼我們在lua中怎麼呼叫這些函式呢?

<pre name="code" class="html">typedef struct luaL_Reg {
  const char *name;
  lua_CFunction func;
} luaL_Reg;
 
   


lua為定義了這樣一個結構體,name表示在lua中的函式名字,func表示name真正呼叫的函式

3.簡短的說下luaopen_math函式呼叫過程

當我們對映表好了後,要如何註冊?

如今比較具體的說下:

LUAMOD_API int luaopen_math (lua_State *L) {
  luaL_newlib(L, mathlib);
  lua_pushnumber(L, PI);
  lua_setfield(L, -2, "pi");
  lua_pushnumber(L, HUGE_VAL);
  lua_setfield(L, -2, "huge");
  return 1;
}

luaL_newlib:這個函式一個巨集:建立一個table來儲存我們對映資料(key-value值)。