Lua Api 簡單範例

lua-users home
wiki

這是如何從 C 介接 Lua 的簡單入門範例。C 程式載入一個 Lua 程式檔,設定一些 Lua 變數,執行 Lua 程式,並讀取回傳值。底下的範例適用於 Lua 5.3。

首先,建立底下的 Lua 程式檔,並儲存為「script.lua」。這個程式將把一個名為「foo」的表格內容(將由 C 程式建立)傾印到畫面上,並回傳這個表格所有組成的總和。

-- script.lua
-- Receives a table, returns the sum of its components.
io.write("The table the script received has:\n");
x = 0
for i = 1, #foo do
  print(i, foo[i])
  x = x + foo[i]
end
io.write("Returning data back to C\n");
return x

為了從 C 取用它,我們可以寫一個會建構表格、將表格傳遞到程式,以及取得回傳值的簡單程式。建立一個名為「test.c」的 C 程式,如下所示

/*
 * test.c
 * Example of a C program that interfaces with Lua.
 * Based on Lua 5.0 code by Pedro Martelletto in November, 2003.
 * Updated to Lua 5.1. David Manura, January 2007.
 */

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <stdlib.h>
#include <stdio.h>


int
main(void)
{
    int status, result, i;
    double sum;
    lua_State *L;

    /*
     * All Lua contexts are held in this structure. We work with it almost
     * all the time.
     */
    L = luaL_newstate();

    luaL_openlibs(L); /* Load Lua libraries */

    /* Load the file containing the script we are going to run */
    status = luaL_loadfile(L, "script.lua");
    if (status) {
        /* If something went wrong, error message is at the top of */
        /* the stack */
        fprintf(stderr, "Couldn't load file: %s\n", lua_tostring(L, -1));
        exit(1);
    }

    /*
     * Ok, now here we go: We pass data to the lua script on the stack.
     * That is, we first have to prepare Lua's virtual stack the way we
     * want the script to receive it, then ask Lua to run it.
     */
    lua_newtable(L);    /* We will pass a table */

    /*
     * To put values into the table, we first push the index, then the
     * value, and then call lua_rawset() with the index of the table in the
     * stack. Let's see why it's -3: In Lua, the value -1 always refers to
     * the top of the stack. When you create the table with lua_newtable(),
     * the table gets pushed into the top of the stack. When you push the
     * index and then the cell value, the stack looks like:
     *
     * <- [stack bottom] -- table, index, value [top]
     *
     * So the -1 will refer to the cell value, thus -3 is used to refer to
     * the table itself. Note that lua_rawset() pops the two last elements
     * of the stack, so that after it has been called, the table is at the
     * top of the stack.
     */
    for (i = 1; i <= 5; i++) {
        lua_pushnumber(L, i);   /* Push the table index */
        lua_pushnumber(L, i*2); /* Push the cell value */
        lua_rawset(L, -3);      /* Stores the pair in the table */
    }

    /* By what name is the script going to reference our table? */
    lua_setglobal(L, "foo");

    /* Ask Lua to run our little script */
    result = lua_pcall(L, 0, LUA_MULTRET, 0);
    if (result) {
        fprintf(stderr, "Failed to run script: %s\n", lua_tostring(L, -1));
        exit(1);
    }

    /* Get the returned value at the top of the stack (index -1) */
    sum = lua_tonumber(L, -1);

    printf("Script returned: %.0f\n", sum);

    lua_pop(L, 1);  /* Take the returned value out of the stack */
    lua_close(L);   /* Cya, Lua */

    return 0;
}

現在是時候編譯它了。請記住,您需要連結到 -llua(Lua),可能還要連結到 -lm (math 函式庫)。在我撰寫這個簡單測試的系統中,「cc -o test test.c -I/usr/local/include -L/usr/local/lib -llua -lm」如預期產生二進位檔。在其他系統(OpenSuse 11.4,gcc4.7),-ldl 也必須用於解析「dlopen」等未定義的參照。

最後,執行測試,您應該會得到類似

$ ./test                                           
The table the script received has:
1       2
2       4
3       6
4       8
5       10
Returning data back to C
Script returned: 30

這會示範基礎 API 如何作用,以及如何在 C 和 Lua 之間傳遞值。

如需更多資訊,請參閱 [Lua API Demo]。它是一個特別為 Lua 編譯器設計的模組,它讓您可以設定一個具有堆疊的假 Lua 狀態,呼叫 Lua API 函式,並觀察它們對堆疊的影響。


最新異動 · 喜好設定
編輯 · 歷程
最近編輯時間為 2018 年 3 月 2 日 上午 7:09 GMT (diff)