第一版是為 Lua 5.0 所寫。雖然對後來的版本仍然有很大的關聯性,但還是有些不同。
第四版針對 Lua 5.3,可以在 Amazon 和其他書店買到。
購買這本書,您也可以 贊助 Lua 計畫


25.2 – 呼叫 Lua 函數

Lua 的一大優點是,設定檔可以定義函數供應用程式呼叫。例如,您可以寫一個應用程式來繪製函數的圖形,並使用 Lua 來定義要繪製的函數。

呼叫函數的 API 協定很簡單:首先,您將要呼叫的函數推入堆疊;其次,您將呼叫的引數推入堆疊;然後,您使用 lua_pcall 來執行實際呼叫;最後,您將結果從堆疊中彈出。

舉例來說,假設我們的設定檔有一個函數如下

    function f (x, y)
      return (x^2 * math.sin(y))/(1 - x)
    end
而且您想要在 C 中評估 z = f(x, y),其中 xy 已知。假設您已經開啟 Lua 函式庫並執行設定檔,您可以將此呼叫封裝在下列 C 函數中
    /* call a function `f' defined in Lua */
    double f (double x, double y) {
      double z;
    
      /* push functions and arguments */
      lua_getglobal(L, "f");  /* function to be called */
      lua_pushnumber(L, x);   /* push 1st argument */
      lua_pushnumber(L, y);   /* push 2nd argument */
    
      /* do the call (2 arguments, 1 result) */
      if (lua_pcall(L, 2, 1, 0) != 0)
        error(L, "error running function `f': %s",
                 lua_tostring(L, -1));
    
      /* retrieve result */
      if (!lua_isnumber(L, -1))
        error(L, "function `f' must return a number");
      z = lua_tonumber(L, -1);
      lua_pop(L, 1);  /* pop returned value */
      return z;
    }

您使用 lua_pcall,並提供您要傳遞的引數數量和您要的結果數量。第四個引數表示錯誤處理函數;我們稍後會討論。如同在 Lua 指派中,lua_pcall 會將實際的結果數量調整為您要求的數量,視需要推入 nil 或捨棄多餘的值。在推入結果之前,lua_pcall 會從堆疊中移除函數及其引數。如果函數傳回多個結果,第一個結果會先被推入;因此,如果有 n 個結果,第一個結果會在索引 -n,最後一個結果會在索引 -1

如果在執行 lua_pcall 時發生任何錯誤,lua_pcall 會傳回一個非零的值;此外,它會將錯誤訊息推入堆疊中(但仍會彈出函式及其引數)。不過,在推入訊息之前,lua_pcall 會呼叫錯誤處理函式(如果有的話)。若要指定錯誤處理函式,我們使用 lua_pcall 的最後一個引數。零表示沒有錯誤處理函式;也就是說,最終的錯誤訊息就是原始訊息。否則,該引數應該是錯誤處理函式位於堆疊中的索引。請注意,在這種情況下,必須在要呼叫的函式及其引數之前將處理常式推入堆疊中。

對於一般錯誤,lua_pcall 會傳回錯誤代碼 LUA_ERRRUN。有兩種特殊類型的錯誤值得使用不同的代碼,因為它們永遠不會執行錯誤處理常式。第一種類型是記憶體配置錯誤。對於此類錯誤,lua_pcall 始終會傳回 LUA_ERRMEM。第二種類型是在 Lua 執行錯誤處理常式本身時發生的錯誤。在這種情況下,再次呼叫錯誤處理常式幾乎沒有用處,因此 lua_pcall 會立即傳回代碼 LUA_ERRERR