美文网首页
C API-调用LUA函数

C API-调用LUA函数

作者: 烫烫烫烫烫烫烫烫烫烫烫烫 | 来源:发表于2019-05-06 16:59 被阅读0次

lua_pcall 函数

lua_pcall 可以执行lua代码 前面的例子中load时就执行了lua脚本或者lua编译文件

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

nargs: 待调用函数的参数数量
nresults: 期望的结果个数
errfunc: 处理错误函数的索引

就像 settop函数的赋值一样,lua_pcall 会根据要求的数量来调整实际参数,即压入nil或者丢弃多余的结果。压入一个结果前,lua_pcall会向删除栈中的函数以及参数。如果一个函数有多个返回值,那么第一个结果最先入栈。

如果lua_pcall在运行时有任何错误,lua_pcall会返回一个非零值,并且在栈中压入一条错误消息。不过即使如此,它仍然会弹出函数以及参数。然而,在压入错误消息前,如果存在一个错误处理函数,lua_pcall会调用它。通过lua_pcall的最后一个参数可以指定错误处理函数。0表示没有错误处理函数,那么最终的消息就是原来的错误消息。如果传入非零值,那么这个参数就应该时一个处务处理函数在栈中的索引,因此,错误处理函数必须先压入栈中,也就是必须位于待调用函数机器参数的下面,先其入栈。

对于一个普通的错误,lua_pcall返回错误代码LUA_ERRRUN。担忧两种特殊的错误情况,不会运行错误处理函数。第一种时内存分配错误,这类错误lua_pcall总是返回LUA_ERRMEM。第二类错误发生在lua运行错误处理函数时,在这种情况没有必要再次调用错误处理函数,因此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;
    //压入函数和参数
    lua_getglobal(L, "f"); //待调用的函数
    lua_pushnumber(L, x); //压入第一个参数
    lua_pushnumber(L, y); //压入第二个参数
    stack_dump(L);
    //完成调用 (2个参数  1个结果) 执行之后,压入的变量会被弹出
    if (lua_pcall(L, 2, 1, 0) != 0) {
        error(L, "error running function 'f' :%s \n", lua_tostring(L, -1));
    }
    stack_dump(L);
    //检索结果
    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);// 弹出结果
    lua_pop(L, 1); //把结果 以及压入的函数和参数弹出
    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 发生错误,两个函数都会把错误消息压入栈,并返回一个非零的错误代码,可以通过lua_tostring获得错误信息
        error(L, "error cannot run config  file:%s\n", lua_tostring(L, -1));
    }
    
}

int main() {
    lua_State* L = luaL_newstate();
    luaL_openlibs(L); //打开标准库  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");
}

相关文章

  • C API-调用LUA函数

    lua_pcall 函数 lua_pcall 可以执行lua代码 前面的例子中load时就执行了lua脚本或者lu...

  • lua和c的初始

    lua和c的交互包括:c访问lua的变量、c访问lua的table、c调用lua的方法、lua调用c的函数 参考链...

  • 对Lua ,C,C#互相调用的理解

    几种情况讨论 C调用Lua C调用C# C#调用C C#调用Lua Lua调用C Lua调用C# Lua调用C 本...

  • tolua调用c#函数及变量

    比如说你要调用一个lua函数 但你想把自身传给lua函数让这个函数调用c# 类的其他函数以及变量 首先是调用lua...

  • 鹅厂实习周记(三)之Lua 使用C函数生成的so动态链接库

    Lua是可以调用C函数的,将c函数生成so库就可以动态链接进lua中调用啦。但是觉得坑还是挺多的。主要原因: 生成...

  • 三、Lua调用C++函数

    上一篇文章中我们已经知道了,C++怎么调用Lua中的函数,接下来我们学习一下,Lua怎么调用C++中的函数。 这篇...

  • lua调用c++中的函数(使用LuaBridge)

    前面一节简述描写了如何在c++中调用lua函数,这节简述描写如何在lua中调用c++中的函数,还是使用前一节的工程...

  • Lua绑定流程

    绑定是为了实现将C++代码注册到lua环境,使得lua可以调用C++函数。https://blog.csdn.ne...

  • Lua与C进行交互

    1 预备知识 1.1 接口函数 接口函数都是由Lua虚拟机提供的,供C程序调用的函数 lua.h里的所有函数都是以...

  • C++调用lua方式

    目标 使用C++调用lua接口 示例 lua代码(test.lua) C++调用示例(lua_test.cpp) ...

网友评论

      本文标题:C API-调用LUA函数

      本文链接:https://www.haomeiwen.com/subject/rbsdoqtx.html