我想从C调用一个外部Lua_5.2函数,所以我做了一个最小的例子来试用它.

最小测试文件:

--- filename: play.lua
function hello()
    print("Hello World!\n")
end

try 从C:调用此函数:

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

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"


int
main(void) {
    lua_State *L;
    int status;
    int result;

    L = luaL_newstate();
    luaL_openlibs(L);

    status = luaL_loadfile(L, "play.lua");
    if (status != LUA_OK) {
        fprintf(stderr, "Could not load 'play.lua'!");
        exit(1);
    }

    lua_getglobal(L, "hello");
    if (lua_isfunction(L, -1)) {
        fprintf(stderr, "ERROR: Not a function!\n");
        exit(1);
    }

    result = lua_pcall(L, 0, 0, 0);
    if (result!= LUA_OK) {
        fprintf(sterr, "Error running lua: %i\n", result);
        exit(1);
    }
    fprintf(stdout, "lua ran fine\n");
    lua_pop(L, lua_gettop(L));

    lua_close(L);
    return 0;
}

但是,调用该可执行文件会产生lua_errun(2)

Error running lua: 2

我不太确定我在这里做错了什么,文档对我来说有点不透明--根据我正确使用的5.2 reference manual,pcall(具有零参数和零返回值的函数),而且我显然是正确地从堆栈中获取了函数(否则他们前面的错误就会显示).

你知道我做错了什么吗?

推荐答案

当返回值lua_pcallnot LUA_OK时,错误消息将被推送到堆栈的顶部.

可以使用像lua_tostring这样的函数来操作该值,以便在C中使用.

result = lua_pcall(L, 0, 0, 0);

if (result != LUA_OK) {
    fprintf(stderr, "Error running lua: %s\n", lua_tostring(L, -1));
    exit(1);
}

(You can also propagate the error with 100, but that may defeat the purpose of the protected call.)

执行此操作会显示错误

Error running lua: attempt to call a nil value

这意味着lua_getglobal(L, "hello");nil推入堆栈.

(Note that we only get this far because 100 is the inverse condition to check for.)

全局变量hello的值是nil,因为包含其定义的chunk从未执行过.也就是说,luaL_loadfile个(最终是lua_load个)只有loads个块,它不执行它们.

加载块后,您可以像执行任何其他函数一样执行它(lua_call等).

例如:

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

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

int
main(void) {
    lua_State *L = luaL_newstate();

    luaL_openlibs(L);

    int status;
    int result;

    status = luaL_loadfile(L, "play.lua"); /* load the chunk */
    if (status != LUA_OK) {
        fprintf(stderr, "Could not load 'play.lua': %s\n", lua_tostring(L, -1));
        exit(1);
    }

    result = lua_pcall(L, 0, 0, 0); /* execute the chunk */
    if (result != LUA_OK) {
        fprintf(stderr, "Error running lua: %s\n", lua_tostring(L, -1));
        exit(1);
    }

    lua_getglobal(L, "hello");
    if (!lua_isfunction(L, -1)) {
        fprintf(stderr, "ERROR: Not a function!\n");
        exit(1);
    }

    result = lua_pcall(L, 0, 0, 0);
    if (result != LUA_OK) {
        fprintf(stderr, "Error running lua: %s\n", lua_tostring(L, -1));
        exit(1);
    }

    puts("lua ran fine");
    lua_close(L);
}

输出:

Hello World!

lua ran fine

请注意,luaL_dofile是定义为

(luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))

并且是加载和执行块的便捷方式.

C++相关问答推荐

了解一些CLIPS原语数据类型

单指针和空参数列表之间的函数指针兼容性

为什么在Linux(特别是Ubuntu 20.04LTS)上,POSIX共享内存对象在重启后仍然存在,然后突然变成了根用户?

为什么删除CAP_DAC_OVERRIDE后创建文件失败?

将fget()与strcMP()一起使用不是正确的比较

如何使用[BTStack]BLE发送大型(>;2kb)信息包

限制不同类型的限定符

获取每个循环迭代结束时的当前时间

在创建动态泛型数组时,通过realloc对故障进行分段

如何按顺序将所有CSV文件数据读入 struct 数组?

Caesar密码调试:输出文本末尾的问号和随机字符

为什么我在C代码中得到一个不完整的类型?

有没有一种方法可以用C创建保留限定符的函数?

隐藏测试用例无法在c程序中计算位数.

宏观;S C调深度

发送和接收的消息中的Unix域套接字不匹配

在printf()中用%.*S格式填充长度为0的字符串是否会调用任何UB?如果是,是哪一个?

Makefile无法将代码刷新到ATmega328p

C struct 中的冒泡排序

OpenGL 中的非渐变 colored颜色 变化