我正在尝试学习Lua以及如何与C进行交互。我的第一次尝试如下,但已被简化为仅包括我所看到的问题。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/limits.h> /* For PATH_MAX */
#include <unistd.h>
#include <getopt.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#define EXITF exit(EXIT_FAILURE)
lua_State* lua;
void stackDump(lua_State* lua)
{
int i, t;
int top = lua_gettop(lua);
for (i = 1; i <= top; i++)
{
t = lua_type(lua, i);
switch (t)
{
case LUA_TSTRING:
printf("\"%s\"", lua_tostring(lua, i));
break;
case LUA_TBOOLEAN:
printf(lua_toboolean(lua, i) ? "true" : "false");
case LUA_TNUMBER:
printf("%g", lua_tonumber(lua, i));
break;
default:
printf("%s", lua_typename(lua, t));
break;
}
if (i < top)
printf(", ");
}
printf("\n");
}
int main(int argc, char** argv)
{
int opt;
char cfgFile[PATH_MAX];
cfgFile[0] = 0;
lua = luaL_newstate();
luaL_openlibs(lua);
stackDump(lua);
while ((opt = getopt(argc, argv, "c:")) != -1)
{
switch (opt)
{
case 'c':
strncpy(cfgFile, optarg, PATH_MAX);
cfgFile[PATH_MAX - 1] = 0;
break;
}
}
if (cfgFile[0] == 0)
{
fprintf(stderr, "No cfg file specified\n");
return EXIT_FAILURE;
}
printf("cfgFile = \"%s\"\n", cfgFile);
if (luaL_loadfile(lua, cfgFile) != LUA_OK)
{
fprintf(stderr, "%s\n", lua_tostring(lua, -1));
lua_pop(lua, 1);
lua_close(lua);
return EXIT_FAILURE;
}
stackDump(lua);
lua_getglobal(lua, "program");
stackDump(lua);
if (lua_isstring(lua, -1) == 0)
{
fprintf(stderr, "`program` should be a string\n");
lua_close(lua);
return EXIT_FAILURE;
}
char execArg0[256];
strncpy(execArg0, lua_tostring(lua, -1), 256);
lua_pop(lua, 1);
lua_close(lua);
return EXIT_SUCCESS;
}
Lua脚本:
#!/usr/bin/env lua
program = "echo"
我在运行时看到的是:
$ ./wrapper2 -c wrapper2.lua
cfgFile = "wrapper2.lua"
function
function, nil
`program` should be a string
请注意,空行是有意的; stackDump()
告诉我们此时堆栈是空的。似乎对lua_getglobal(lua, "program")
的调用正在推送nil
而不是字符串"echo"
。请问你能帮我弄明白为什么我会看到这个吗?
作为一个侧面问题:为什么在堆栈上推送了一个函数(可能是luaL_loadfile()
)?我不记得读过自动将功能推到堆栈上。
答案 0 :(得分:3)
luaL_loadfile
加载Lua脚本但不执行它,因此不会定义全局program
。请改用luaL_dofile
。
luaL_loadfile
编译一个Lua脚本,并将代码保留为堆栈中的Lua函数。
luaL_dofile
调用luaL_loadfile
,然后调用该函数。
请参阅luaL_loadfile和luaL_dofile的手册条目。