从C获取Lua字符串

时间:2015-09-30 18:53:27

标签: c lua

我正在尝试学习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())?我不记得读过自动将功能推到堆栈上。

1 个答案:

答案 0 :(得分:3)

luaL_loadfile加载Lua脚本但不执行它,因此不会定义全局program。请改用luaL_dofile

luaL_loadfile编译一个Lua脚本,并将代码保留为堆栈中的Lua函数。

luaL_dofile调用luaL_loadfile,然后调用该函数。

请参阅luaL_loadfileluaL_dofile的手册条目。