C API-調(diào)用LUA函數(shù)

lua_pcall 函數(shù)

lua_pcall 可以執(zhí)行l(wèi)ua代碼 前面的例子中l(wèi)oad時(shí)就執(zhí)行了lua腳本或者lua編譯文件

    int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);

nargs: 待調(diào)用函數(shù)的參數(shù)數(shù)量
nresults: 期望的結(jié)果個(gè)數(shù)
errfunc: 處理錯(cuò)誤函數(shù)的索引

就像 settop函數(shù)的賦值一樣蚪缀,lua_pcall 會根據(jù)要求的數(shù)量來調(diào)整實(shí)際參數(shù)但狭,即壓入nil或者丟棄多余的結(jié)果。壓入一個(gè)結(jié)果前,lua_pcall會向刪除棧中的函數(shù)以及參數(shù)矛紫。如果一個(gè)函數(shù)有多個(gè)返回值,那么第一個(gè)結(jié)果最先入棧。

如果lua_pcall在運(yùn)行時(shí)有任何錯(cuò)誤,lua_pcall會返回一個(gè)非零值借卧,并且在棧中壓入一條錯(cuò)誤消息。不過即使如此筛峭,它仍然會彈出函數(shù)以及參數(shù)铐刘。然而,在壓入錯(cuò)誤消息前影晓,如果存在一個(gè)錯(cuò)誤處理函數(shù)镰吵,lua_pcall會調(diào)用它。通過lua_pcall的最后一個(gè)參數(shù)可以指定錯(cuò)誤處理函數(shù)挂签。0表示沒有錯(cuò)誤處理函數(shù)疤祭,那么最終的消息就是原來的錯(cuò)誤消息。如果傳入非零值饵婆,那么這個(gè)參數(shù)就應(yīng)該時(shí)一個(gè)處務(wù)處理函數(shù)在棧中的索引勺馆,因此,錯(cuò)誤處理函數(shù)必須先壓入棧中侨核,也就是必須位于待調(diào)用函數(shù)機(jī)器參數(shù)的下面草穆,先其入棧。

對于一個(gè)普通的錯(cuò)誤搓译,lua_pcall返回錯(cuò)誤代碼LUA_ERRRUN悲柱。擔(dān)憂兩種特殊的錯(cuò)誤情況,不會運(yùn)行錯(cuò)誤處理函數(shù)些己。第一種時(shí)內(nèi)存分配錯(cuò)誤豌鸡,這類錯(cuò)誤lua_pcall總是返回LUA_ERRMEM。第二類錯(cuò)誤發(fā)生在lua運(yùn)行錯(cuò)誤處理函數(shù)時(shí)段标,在這種情況沒有必要再次調(diào)用錯(cuò)誤處理函數(shù)直颅,因此lua_pcall會立即返回LUA_ERRERR

代碼示例:
load_func.lua

function f (x, y) 
       return (x^2 * math.sin(y)) / (1-x)
end

main.cc

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

#ifdef __cplusplus
extern "C" {
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}

#endif // __cplusplus

static void stack_dump(lua_State *L) {
    int i;
    int top = lua_gettop(L);//
    printf("stack len:%d  ", top);
    for (i = 1; i <= top; i++) {
        int t = lua_type(L, i);
        switch (t) {
        case LUA_TSTRING: {
            printf("'%s'", lua_tostring(L, i));
            break;
        }
        case LUA_TBOOLEAN: {
            printf(lua_toboolean(L, i) ? "true" : "false");
            break;
        }
        case LUA_TNUMBER: {
            printf("%g", lua_tonumber(L, i));
            break;
        }
        default:
            printf("%s", lua_typename(L, t));
            break;
        }
        printf("  ");
    }
    printf("\n");
}


void error(lua_State *L, const char* fmt, ...) {
    va_list argp;
    va_start(argp, fmt);
    vfprintf(stderr, fmt, argp);
    va_end(argp);
    lua_close(L);
    exit(EXIT_FAILURE);
}

double f(lua_State* L, double x, double y) {
    double z;
    //壓入函數(shù)和參數(shù)
    lua_getglobal(L, "f"); //待調(diào)用的函數(shù)
    lua_pushnumber(L, x); //壓入第一個(gè)參數(shù)
    lua_pushnumber(L, y); //壓入第二個(gè)參數(shù)
    stack_dump(L);
    //完成調(diào)用 (2個(gè)參數(shù)  1個(gè)結(jié)果) 執(zhí)行之后,壓入的變量會被彈出
    if (lua_pcall(L, 2, 1, 0) != 0) {
        error(L, "error running function 'f' :%s \n", lua_tostring(L, -1));
    }
    stack_dump(L);
    //檢索結(jié)果
    if (!lua_isnumber(L, -1)) {
        error(L, "error running function 'f' must return a number :%s \n", lua_tostring(L, -1));
    }

    z = lua_tonumber(L, -1);// 彈出結(jié)果
    lua_pop(L, 1); //把結(jié)果 以及壓入的函數(shù)和參數(shù)彈出
    stack_dump(L);
    return z;
}

void load(lua_State* L, const char* fname) {
    if (luaL_loadfile(L, fname) || lua_pcall(L, 0, 0, 0)) {
        //luaL_loadfile\lua_pcall 發(fā)生錯(cuò)誤怀樟,兩個(gè)函數(shù)都會把錯(cuò)誤消息壓入棧,并返回一個(gè)非零的錯(cuò)誤代碼盆佣,可以通過lua_tostring獲得錯(cuò)誤信息
        error(L, "error cannot run config  file:%s\n", lua_tostring(L, -1));
    }
    
}

int main() {
    lua_State* L = luaL_newstate();
    luaL_openlibs(L); //打開標(biāo)準(zhǔn)庫  lualib.h
        
    load(L, "./load_func.lua");

    double x = 2.5f;
    double y = 3.0f;
    double z = 0.0f;
    z = f(L, x, y);
    printf("function f result is %g \n", z);

    lua_close(L);
    system("pause");
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末往堡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子共耍,更是在濱河造成了極大的恐慌虑灰,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痹兜,死亡現(xiàn)場離奇詭異穆咐,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門对湃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來崖叫,“玉大人,你說我怎么就攤上這事拍柒⌒目” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵拆讯,是天一觀的道長脂男。 經(jīng)常有香客問我,道長种呐,這世上最難降的妖魔是什么宰翅? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮爽室,結(jié)果婚禮上汁讼,老公的妹妹穿的比我還像新娘。我一直安慰自己肮之,他們只是感情好掉缺,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著戈擒,像睡著了一般眶明。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上筐高,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天搜囱,我揣著相機(jī)與錄音,去河邊找鬼柑土。 笑死蜀肘,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的稽屏。 我是一名探鬼主播扮宠,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼狐榔!你這毒婦竟也來了坛增?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤薄腻,失蹤者是張志新(化名)和其女友劉穎收捣,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體庵楷,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡罢艾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年楣颠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咐蚯。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡童漩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出仓蛆,到底是詐尸還是另有隱情睁冬,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布看疙,位于F島的核電站豆拨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏能庆。R本人自食惡果不足惜施禾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望搁胆。 院中可真熱鬧弥搞,春花似錦、人聲如沸渠旁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽顾腊。三九已至粤铭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間杂靶,已是汗流浹背梆惯。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吗垮,地道東北人垛吗。 一個(gè)月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像烁登,于是被迫代替她去往敵國和親怯屉。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,763評論 0 38
  • 原文地址:C語言函數(shù)調(diào)用棧(一)C語言函數(shù)調(diào)用棧(二) 0 引言 程序的執(zhí)行過程可看作連續(xù)的函數(shù)調(diào)用饵沧。當(dāng)一個(gè)函數(shù)執(zhí)...
    小豬啊嗚閱讀 4,595評論 1 19
  • 第一篇 語言 第0章 序言 Lua僅讓你用少量的代碼解決關(guān)鍵問題蚀之。 Lua所提供的機(jī)制是C不擅長的:高級語言,動(dòng)態(tài)...
    testfor閱讀 2,657評論 1 7
  • 當(dāng)在Lua和C之間交換數(shù)據(jù)時(shí)主要的問題是自動(dòng)回收與手動(dòng)回收內(nèi)存管理的不一致捷泞。因此,Lua 用一個(gè)抽象的棧在Lua與...
    luffier閱讀 2,639評論 0 3
  • lua語言的功能就不用過多的描述寿谴,詳細(xì)的可以去找相關(guān)的lua書籍去看看锁右!這里主要說的是c++和lua相互調(diào)用的情況...
    David_Longzy閱讀 1,660評論 0 2