英文:
Calling Lua Function from C: Minimal example results in LUA_ERRRUN
问题
我想从C中调用一个外部的lua_5.2函数,所以我创建了一个最小的示例来尝试。
最小的测试文件:
--- 文件名: play.lua
function hello()
print("Hello World!\n")
end
尝试从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, "无法加载 'play.lua'!");
exit(1);
}
lua_getglobal(L, "hello");
if (lua_isfunction(L, -1)) {
fprintf(stderr, "错误:不是一个函数!\n");
exit(1);
}
result = lua_pcall(L, 0, 0, 0);
if (result != LUA_OK) {
fprintf(stderr, "运行lua时出错:%i\n", result);
exit(1);
}
fprintf(stdout, "lua运行正常\n");
lua_pop(L, lua_gettop(L));
lua_close(L);
return 0;
}
然而,调用该可执行文件会导致LUA_ERRRUN (2) 错误:
运行lua时出错:2
我不太确定我在这里做错了什么,文档对我来说有点模糊不清 - 根据5.2参考手册,我正在正确使用pcall
(零参数和零返回值的函数),而且我显然正确地从堆栈中获取了函数(否则之前的错误将会显示)。
你有任何关于我做错了什么的想法吗?
英文:
I want to call an external lua_5.2 function from C, so I made a minimal example to try it out.
The minimal testfile:
--- filename: play.lua
function hello()
print("Hello World!\n")
end
Trying to call this function from 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;
}
Calling that executable results however in LUA_ERRUN (2)
Error running lua: 2
I am not quite sure what I am doing wrong here, and the documentation is a little bit opaque to me -- according to the 5.2 reference manual I am using pcall
correctly (function with zero args and zero return vals), and I apparently grabbed the function from the stack correctly (otherwise they earlier error would have shown).
Any idea what I am doing wrong?
答案1
得分: 2
当lua_pcall
的返回值不是 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);
}
(您还可以使用lua_error(L)
传播错误,但这可能会违反受保护的调用的目的。)
执行此操作会显示错误消息
Error running lua: attempt to call a nil value
这意味着 lua_getglobal(L, "hello");
推送了 nil 到堆栈上。
(请注意,我们之所以能够进行到这一步,是因为 if (lua_isfunction(L, -1))
是用于检查的相反条件。)
全局变量 hello
的值是 nil,因为包含其定义的块从未被执行过。也就是说,luaL_loadfile
(最终是lua_load
)只是 加载 块,而不会执行它们。
加载块后,可以像执行任何其他函数一样执行它(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"); /* 加载块 */
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); /* 执行块 */
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))
这是一种方便的加载和执行块的方式。
英文:
When the return value of lua_pcall
is not LUA_OK
, an error message will have been pushed onto the top of the stack.
This value can be manipulated with functions like lua_tostring
for use in 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 lua_error(L)
, but that may defeat the purpose of the protected call.)
Doing this reveals the error
Error running lua: attempt to call a nil value
which means lua_getglobal(L, "hello");
pushed nil onto the stack.
(Note that we only get this far because if (lua_isfunction(L, -1))
is the inverse condition to check for.)
The value of the global variable hello
is nil because the chunk containing its definition was never executed. That is, luaL_loadfile
(ultimately lua_load
) only loads chunks, it does not execute them.
After loading a chunk, you may execute it like any other function (lua_call
, etc.).
For example:
#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);
}
Output:
Hello World!
lua ran fine
Note that luaL_dofile
is a macro defined as
(luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
and is a convenient way to load and execute a chunk.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论