佳木斯湛栽影视文化发展公司

主頁(yè) > 知識(shí)庫(kù) > Lua教程(二):C++和Lua相互傳遞數(shù)據(jù)示例

Lua教程(二):C++和Lua相互傳遞數(shù)據(jù)示例

熱門(mén)標(biāo)簽:百度競(jìng)價(jià)排名 呼叫中心市場(chǎng)需求 Linux服務(wù)器 網(wǎng)站排名優(yōu)化 鐵路電話(huà)系統(tǒng) AI電銷(xiāo) 地方門(mén)戶(hù)網(wǎng)站 服務(wù)外包

這是我的Lua系列教程的第二篇,本篇文章主要介紹C++和Lua相互傳遞數(shù)據(jù)。如果你還不知道怎么在c/c++里面調(diào)用Lua腳本的話(huà),請(qǐng)參考這篇文章. 本文主要介紹基本數(shù)據(jù)類(lèi)型的傳遞,比如整形(int),字符串(string)、數(shù)字(number)及bool值。

加載并運(yùn)行Lua腳本

由于在上一個(gè)教程里面已經(jīng)介紹過(guò)如何在C/C++里面嵌入Lua,所以這一節(jié)就簡(jiǎn)單的介紹一下程序怎么用,配置就略過(guò)啦。

創(chuàng)建Lua虛擬機(jī)

復(fù)制代碼 代碼如下:

lua_State *lua_state = luaL_newstate();

加載Lua庫(kù)

復(fù)制代碼 代碼如下:

static const luaL_Reg lualibs[] =
    {
        {"base", luaopen_base},
        {"io", luaopen_io},
        {NULL, NULL}
    };
    const luaL_Reg *lib = lualibs;
    for(; lib->func != NULL; lib++)
    {
        luaL_requiref(lua_state, lib->name, lib->func, 1);
        lua_pop(lua_state,1);
    }

運(yùn)行Lua腳本

復(fù)制代碼 代碼如下:

std::string scriptPath = FileUtils::getInstance()->fullPathForFilename("hello.lua");
int status = luaL_loadfile(lua_state, scriptPath.c_str());
std::cout " return: " status std::endl;
int result = 0;
if(status == LUA_OK)
{
    result = lua_pcall(lua_state, 0, LUA_MULTRET, 0);
}
else
{
    std::cout " Could not load the script." std::endl;
}

這里我們使用的是luaL_loadfile而不是之前的luaL_dofile,其實(shí)luaL_dofile只是一個(gè)宏定義:

復(fù)制代碼 代碼如下:

#define luaL_dofile(L, fn) \
    (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))

我們先調(diào)用luaL_loadfile可以判斷Lua腳本是否加載成功,然后再調(diào)用lua_pcall來(lái)執(zhí)行Lua腳本。

C/C++調(diào)用Lua函數(shù)

首先,我們?cè)趆ello.lua里面定義一個(gè)lua函數(shù):

復(fù)制代碼 代碼如下:

-- add two numbers
function add ( x, y )
    return x + y
end

Lua的函數(shù)定義是以function為keyword,然后以end結(jié)尾,同時(shí)它的參數(shù)是沒(méi)有形參類(lèi)型的,另外,Lua的函數(shù)可以返回多個(gè)值。不過(guò)我們這里只返回了一個(gè)值。

接下來(lái),讓我們看看如果在C++程序里面調(diào)用這個(gè)函數(shù):

復(fù)制代碼 代碼如下:

int luaAdd(lua_State *lua_state , int x, int y)
{
    int sum;
    //獲取lua里面的add函數(shù)并把它放到lua的棧頂
    lua_getglobal(lua_state, "add");
    //往lua棧里面壓入兩個(gè)參數(shù)
    lua_pushnumber(lua_state, x);
    lua_pushnumber(lua_state, y);
    //調(diào)用lua函數(shù),這里的2是參數(shù)的個(gè)數(shù),1是返回值的個(gè)數(shù)
    lua_call(lua_state, 2, 1);
    //從棧頂讀取返回值,注意這里的參數(shù)是-1
    sum = lua_tointeger(lua_state, -1);
    //最后我們把返回值從棧頂拿掉
    lua_pop(lua_state, 1);
    return sum;
}

然后,我們就可以在程序里面調(diào)用它了:

復(fù)制代碼 代碼如下:

std::cout "2 + 1= " luaAdd(lua_state,4,1)std::endl;

注意這個(gè)方法調(diào)用要在lua_pcall調(diào)用之后。

操作Lua全局變量

C++里面獲取Lua全局變量的值

首先,我們?cè)趆ello.lua里面定義一個(gè)全局變量

復(fù)制代碼 代碼如下:

myname = "子龍山人"

然后我們?cè)贑++里面訪(fǎng)問(wèn)它:

復(fù)制代碼 代碼如下:

lua_getglobal(lua_state, "myname");
std::string myname = lua_tostring(lua_state, -1);
lua_pop(lua_state, 1);
std::cout"Hello: "mynamestd::endl;

這一次我們又是通過(guò)lua_getglobal來(lái)把myname這個(gè)全局變量壓到lua棧,然后用lua_tostring來(lái)取這個(gè)值。

C++里面修改Lua全局變量的值

這次我們使用的是lua_setglobal來(lái)傳遞數(shù)據(jù)給Lua:

復(fù)制代碼 代碼如下:

lua_pushstring(lua_state, "World");
    lua_setglobal(lua_state, "myname");

這時(shí),我們只要在hello.lua的最開(kāi)始部分,調(diào)用print(myname)就可以打印傳遞進(jìn)來(lái)的值了。

C++傳遞Table給Lua

復(fù)制代碼 代碼如下:

lua_createtable(lua_state, 2, 0);
    lua_pushnumber(lua_state, 1);
    lua_pushnumber(lua_state, 49);
//    lua_settable(lua_state, -3);
    lua_rawset(lua_state, -3);
    lua_pushnumber(lua_state, 2);
    lua_pushstring(lua_state, "Life is a beach");
//    lua_settable(lua_state, -3);
    lua_rawset(lua_state, -3);
    lua_setglobal(lua_state, "arg");

這里我們傳遞了一個(gè)table給lua,這個(gè)table為{49,”Life is a beach”}。Lua table的索引是從1開(kāi)始的,然后我們?cè)趌ua腳本里面可以這樣子來(lái)訪(fǎng)問(wèn)這個(gè)table:

復(fù)制代碼 代碼如下:

for i=1,#arg do
    print("      ", i, arg[i])
end

這里的#arg是獲得table的長(zhǎng)度,然后使用arg[i]來(lái)獲取table的索引i處的value。

Lua返回多個(gè)值給C++

首先是Lua代碼:

復(fù)制代碼 代碼如下:

local temp = {9, "hehehej"}
-- temp[1]=9
-- temp[2]="See you space cowboy!"
return temp,9,1

然后是C++代碼:

復(fù)制代碼 代碼如下:

std::stringstream str_buf;
    while(lua_gettop(lua_state))
    {
        str_buf.str(std::string());
        str_buf " ";
        switch(lua_type(lua_state, lua_gettop(lua_state)))
        {
            case LUA_TNUMBER:
                str_buf "script returned the number: "
                lua_tonumber(lua_state, lua_gettop(lua_state));
                break;
            case LUA_TTABLE:
                str_buf "script returned a table";
                break;
            case LUA_TSTRING:
                str_buf "script returned the string: "
                lua_tostring(lua_state, lua_gettop(lua_state));
                break;
            case LUA_TBOOLEAN:
                str_buf "script returned the boolean: "
                lua_toboolean(lua_state, lua_gettop(lua_state));
                break;
            default:
                str_buf "script returned an unknown-type value";
        }
        lua_pop(lua_state, 1);
        std::cout str_buf.str() std::endl;
    }

最后輸出結(jié)果為:

復(fù)制代碼 代碼如下:

[C++] Values returned from the script:
 script returned the number: 1
 script returned the number: 9
 script returned a table
[C++] Closing the Lua state

在lua里面return值的順序是table,9,1,而在C++里面是倒過(guò)來(lái)的。因?yàn)槲覀兪鞘褂脳W鳛閿?shù)據(jù)結(jié)構(gòu)來(lái)傳遞數(shù)據(jù),而棧是先進(jìn)后出的。

下一篇文章,我們將介紹一下C++調(diào)用Lua的Table。

您可能感興趣的文章:
  • Lua教程(五):C/C++操作Lua數(shù)組和字符串示例
  • Lua教程(四):在Lua中調(diào)用C語(yǔ)言、C++的函數(shù)
  • Lua教程(三):C語(yǔ)言、C++中調(diào)用Lua的Table示例
  • Lua教程(一):在C++中嵌入Lua腳本
  • Lua教程(六):綁定一個(gè)簡(jiǎn)單的C++類(lèi)

標(biāo)簽:崇左 湖南 蘭州 仙桃 衡水 銅川 黃山 湘潭

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Lua教程(二):C++和Lua相互傳遞數(shù)據(jù)示例》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話(huà)咨詢(xún)

    • 400-1100-266
    云梦县| 德令哈市| 雷州市| 合肥市| 攀枝花市| 宜黄县| 专栏| 宝丰县| 宽城| 凯里市| 宁河县| 余姚市| 华蓥市| 贵港市| 道孚县| 孟村| 元朗区| 运城市| 延边| 安多县| 辽宁省| 呼图壁县| 离岛区| 丹棱县| 云浮市| 娱乐| 格尔木市| 桂东县| 汉沽区| 沁源县| 滁州市| 青铜峡市| 连城县| 蓬安县| 环江| 龙泉市| 神农架林区| 平武县| 乐平市| 苗栗市| 兴国县|