将Lua函数块转换为C字符串

时间:2018-10-02 06:16:32

标签: c++ lua

我正在研究一个使用Lua字符串并将其转换为C字符串的项目–当然,这一点都不困难。但是,在尝试将函数的二进制表示形式(即由对string.dump的调用产生的函数形式)转换为C字符串时遇到麻烦。我在读取整个字符串时遇到麻烦。

虽然这不是项目的最终目标,但请考虑以下简单示例,其中我使用已注册供使用的名为chars的C函数将字符串中的字符逐一打印出来。卢阿:

static void chars(char* cp) {
    char* pointer = cp;
    while (*pointer) {
        printf("%c\n", *pointer);
        ++pointer;
    }
    return;
}

static int lua_chars(lua_State* L) {
    lua_len(L, 1);
    size_t len = static_cast<size_t>(lua_tonumber(L, -1)) + 1;
    lua_pop(L, 1);
    if (len > 0) {
        char* cp = static_cast<char*>(malloc(len));
        strcat(cp, lua_tostring(L, 1));
        chars(cp);
        free(cp);
    }
    return 0;
}

从Lua脚本调用chars看起来像这样:

chars("Hello World!")

,然后将字符一一打印出来,然后换行。

现在是实际问题。考虑下面的示例,我在Lua中声明一个函数,用string.dump转储它,然后将该字符串传递给函数chars以分别打印出其字符:

local function foo()
    print("foo")
    return
end

local s = assert(string.dump(foo))
chars(s)

未完全用我的函数s打印的字符串chars看起来像这样:

uaS?

xV(w@=stdin@A@$@&?&?printfoo_ENV

但是,chars仅显示前五个字节:

u
a
S

(请注意,在“ u”之前应该有两行空格。)

我几乎可以肯定这是由于字符串中的空字符所致,我认为这会干扰lua_tostring的功能。我遇到了lua_Writer来读取块,但是我不知道如何使用/编码。如何将Lua堆栈上的整个字符串成功转换为C字符串?

2 个答案:

答案 0 :(得分:2)

问题不是lua_tostring,而是strcat,它会复制直到找到空字符。您的chars函数也有同样的问题。 那应该起作用:

memcpy(cp, lua_tostring(L, 1), len);
chars(cp, len);
...
static void chars(char* cp, size_t len) {
    for (size_t i = 0; i < len; ++i, ++cp) {
        putchar(*cp);
    }
}

答案 1 :(得分:2)

  

我几乎可以肯定,这是由于   字符串

是的,这完全是因为Lua字符串可以包含零。

  

我认为这会干扰lua_tostring的功能。

这是错误的。 lua_tostring()可以正常工作。您正在使用的只是strcat(),只会将数据复制到最接近的零字节。

如果需要复制字符串,请使用memcpy,同时将指向Lua字符串数据的指针和Lua字符串长度(lua_lenlua_rawlen等)传递给它。

但是对于打印,您甚至不需要复制任何内容。将len变量作为参数传递给chars(),并检查该长度而不是等待零字节。