C/C++與Lua交互(C實現的Lua編譯器的例子)

#include <stdio.h>
#include <string.h>

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

#pragma comment(lib,"C:\\Program Files\\Lua\\5.1\\lib\\lua51.lib")

int main (void)
{
    char buff[256];
    int error;
    lua_State *L = lua_open();
    //luaL_openlibs(L);
    luaopen_base(L);
    luaopen_table(L);
    luaopen_io(L);
    luaopen_string(L);
    luaopen_math(L);
    while (fgets(buff, sizeof(buff), stdin) != NULL) {
        error = luaL_loadbuffer(L, buff, strlen(buff),"line") || lua_pcall(L, 0, 0, 0);
        if (error)
        {
            fprintf(stderr, "%s", lua_tostring(L, -1));
            lua_pop(L, 1);
        }
    }
    lua_close(L);
    return 0;
}
該版本是Lua 5.0的例子,若用於Lua 5.1做解釋器,運行到紅色處會出現
PANIC: unprotected error in call to Lua API (no calling environment)
修改後的版本爲:
#include <stdio.h>
#include <string.h>

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

#pragma comment(lib,"C:\\Program Files\\Lua\\5.1\\lib\\lua51.lib")

int main (void)
{
    char buff[256];
    int error;
    lua_State *L = lua_open();
    luaL_openlibs(L);
    //luaopen_base(L);
    //luaopen_table(L);
    //luaopen_io(L);
    //luaopen_string(L);
    //luaopen_math(L);
    //printf("xxxx\n");
    while (fgets(buff, sizeof(buff), stdin) != NULL) {
        error = luaL_loadbuffer(L, buff, strlen(buff),"line") || lua_pcall(L, 0, 0, 0);
        if (error)
        {
            fprintf(stderr, "%s", lua_tostring(L, -1));
            lua_pop(L, 1);
        }
    }
    lua_close(L);
    return 0;
}

頭文件lua.h定義了Lua提供的基礎函數。其中包括創建一個新的Lua環境的函數(如lua_open),調用Lua函數(如lua_pcall)的函數,讀取/寫入Lua環境的全局變量的函數,註冊可以被Lua代碼調用的新函數的函數,等等。所有在lua.h中被定義的都有一個lua_前綴。
   頭文件lauxlib.h定義了輔助庫(auxlib)提供的函數。同樣,所有在其中定義的函數等都以luaL_打頭(例如,luaL_loadbuffer)。輔助庫利用lua.h中提供的基礎函數提供了更高層次上的抽象;所有Lua標準庫都使用了auxlib。基礎API致力於economy and orthogonality,相反auxlib致力於實現一般任務的實用性。當然,基於你的程序的需要而創建其它的抽象也是非常容易的。需要銘記在心的是,auxlib沒有存取Lua內部的權限。它完成它所有的工作都是通過正式的基本API。
   Lua庫沒有定義任何全局變量。它所有的狀態保存在動態結構lua_State中,而且指向這個結構的指針作爲所有Lua函數的一個參數。這樣的實現方式使得Lua能夠重入(reentrant)且爲在多線程中的使用作好準備。
     創建一個state並將標準庫載入之後,就可以着手解釋用戶的輸入了。對於用戶輸入的每一行
while (fgets(buff, sizeof(buff), stdin) ,C程序首先調用luaL_loadbuffer編譯這些Lua代碼。如果沒有錯誤,這個調用返回零並把編譯之後的chunk壓入棧。(記住,我們將在下一節中討論魔法般的棧)之後,C程序調用lua_pcall,它將會把chunk從棧中彈出並在保護模式下運行它。和luaL_laodbuffer一樣,lua_pcall在沒有錯誤的情況下返回零。在有錯誤的情況下,這兩個函數都將一條錯誤消息壓入棧;我們可以用lua_tostring來得到這條信息、輸出它,用lua_pop將它從棧中刪除。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章