Lua函数块转换成C字符串

我正在开发一个项目,将Lua字符串转换为C字符串——当然这并不难。然而,当我尝试将通过调用string.dump生成的二进制函数表示形式转换为C字符串时,我遇到了麻烦。我在读取整个字符串时遇到了问题。

虽然这不是项目的最终目标,但请考虑以下简单的示例,在其中使用我已经注册用于Lua的C函数chars,逐个打印字符串中的字符:

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在完整打印之前看起来像这样:

uaS?

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

但是,chars只打印前五个字节:

u
a
S

(注意'u'之前应该有两行空白。)

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

点赞
用户8572843
用户8572843

问题不在 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);
    }
}
2018-10-02 06:28:54
用户5675002
用户5675002

我几乎可以确定这是由于字符串中有空字符而导致的。

是的,Lua字符串确实可以包含零。

我认为这会影响lua_tostring()的功能。

这是错误的。 lua_tostring()的功能是按预期工作的。只是你使用的strcat()仅将数据复制到最近的零字节。

如果您需要复制字符串,请使用memcpy,将Lua字符串数据指针和Lua字符串长度(lua_lenlua_rawlen等)一起传递。

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

2018-10-02 06:30:40