【问题标题】:Converting a Lua function chunk to a C string将 Lua 函数块转换为 C 字符串
【发布时间】:2018-10-02 14:30:40
【问题描述】:

我正在做一个项目,它采用 Lua 字符串并将其转换为 C 字符串——当然,一点也不难。但是,在尝试将函数的二进制表示(即通过调用 string.dump 生成的函数)转换为 C 字符串时遇到了麻烦。我无法阅读整个字符串。

虽然这不是项目的最终目标,但请考虑以下简单示例,其中我使用已注册用于 Lua 的名为 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 字符串?

【问题讨论】:

  • 请仅标记您实际使用的编程语言。
  • 请参阅lua_tolstring,它会为您提供指向 Lua 字符串中字节和字节数的指针。
  • 如果你使用C++,你应该使用std::string或std::string_view,使用更安全,不依赖空字符。

标签: c++ lua


【解决方案1】:

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

是的,正是因为 Lua 字符串可以包含零。

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

这是错误的。 lua_tostring() 按预期工作。您使用的只是strcat(),只会将数据复制到最接近的零字节。

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

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

【讨论】:

    【解决方案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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-02-02
      • 1970-01-01
      • 2020-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-30
      • 2018-10-02
      • 1970-01-01
      相关资源
      最近更新 更多