Lua 在C程序中调用Lua函数

方法一:调用Lua库函数

调用Lua函数的步骤为:

  1. 获得函数并压入栈
  2. 按顺序压入参数
  3. 调用lua_pcall,该函数的第二个参数是参数个数,第三个参数是返回个数,第四个参数是异常处理函数

示例程序:

//c
/* call a function 'f' defined in Lua */
double f (lua_State *L, double x, double y) {
    int isnum;
    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) != LUA_OK)
        error(L, "error running function 'f': %s",
            lua_tostring(L, -1));
    /* retrieve result */
    z = lua_tonumberx(L, -1, &isnum);
    if (!isnum)
        error(L, "function 'f' must return a number");
        lua_pop(L, 1); /* pop returned value */
    return z;
}

方法二:自定义一个通用的调用Lua函数方法
示例:
定义一个call_va,然后这样调用:

//c
call_va(L, "f", "dd>d", x, y, &z);

第二个参数是函数名,第三个参数是参数和返回值:字符串 “dd>d” 表示函数有两个double 类型的参数,一个double 类型的返回结果。我们使用字母 ‘d’ 表示double;’i’ 表示integer,’s’ 表示strings;’>’ 作为参数和结果的分隔符。如果函数没有返回结果,’>’ 是可选的。

call_va的定义如下:

//c
#include <stdarg.h>
void call_va (lua_State *L, const char *func,
    const char *sig, ...) {
        va_list vl;
        int narg, nres; /* number of arguments and results */
        va_start(vl, sig);
        lua_getglobal(L, func); /* push function */
        for (narg = 0; *sig; narg++) { /* repeat for each argument */
            /* check stack space */
            luaL_checkstack(L, 1, "too many arguments");
            switch (*sig++) {
            case 'd': /* double argument */
                lua_pushnumber(L, va_arg(vl, double));
                break;
            case 'i': /* int argument */
                lua_pushinteger(L, va_arg(vl, int));
                break;
            case 's': /* string argument */
                lua_pushstring(L, va_arg(vl, char *));
                break;
            case '>': /* end of arguments */
                goto endargs;
            default:
                error(L, "invalid option (%c)", *(sig - 1));
            }
        }
endargs:
        nres = strlen(sig); /* number of expected results */
        if (lua_pcall(L, narg, nres, 0) != 0) /* do the call */
            error(L, "error calling '%s': %s", func,
            lua_tostring(L, -1));
        nres = -nres; /* stack index of first result */
        while (*sig) { /* repeat for each result */
            switch (*sig++) {
            case 'd': { /* double result */
                int isnum;
                double n = lua_tonumberx(L, nres, &isnum);
                if (!isnum)
                    error(L, "wrong result type");
                *va_arg(vl, double *) = n;
                break;
                      }
            case 'i': { /* int result */
                int isnum;
                int n = lua_tointegerx(L, nres, &isnum);
                if (!isnum)
                    error(L, "wrong result type");
                *va_arg(vl, int *) = n;
                break;
                      }
            case 's': { /* string result */
                const char *s = lua_tostring(L, nres);
                if (s == NULL)
                    error(L, "wrong result type");
                *va_arg(vl, const char **) = s;
                break;
                      }
            default:
                error(L, "invalid option (%c)", *(sig - 1));
            }
            nres++;
        }
        va_end(vl);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值