如何在 C++ 的 package.preload 中访问本地变量?

以下代码运行良好,如预期输出 3

#include <lua.hpp>
#include <ctime>
#include <chrono>

void main()
{
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);
    lua_settop(L, 0);
    //Script A
    luaL_dostring(L, "package.preload['A'] = function () local A = {}\n"
                     "A.num = 3\n"
                     "return A end");
    //Script B
    luaL_dostring(L, "local A = require 'A' print(A.num)");
    lua_close(L);
}

但是我想在 C++ 中获取 A.num 的值。

我尝试了以下代码,但它并不输出 A.num

lua_getglobal(L, "require");
lua_pushstring(L, "A");
if (lua_pcall(L, 1, LUA_MULTRET, 0) != 0)
{
    std::cerr << "lua:" << lua_tostring(L, 1) << '\n';
    lua_pop(L,1);
}
lua_getglobal(L, "num");
if (lua_type(L, -1) == LUA_TNUMBER)
    std::cout << "A.num : " << lua_tonumber(L, -1) << std::endl;
lua_pop(L, 1);

如何在 C++ 中正确获取 A.num 的值?

点赞
用户1944004
用户1944004

require 'A' 返回一个表。因此,您必须使用 lua_getfield 而不是 lua_getglobal

#include <iostream>

#include <lua.hpp>

int main() {
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);

    luaL_dostring(L, "package.preload['A'] = function () local A = {}\n"
                     "A.num = 3\n"
                     "return A end");

    lua_getglobal(L, "require");
    lua_pushstring(L, "A");
    if (lua_pcall(L, 1, LUA_MULTRET, 0) != 0) {
        std::cerr << "lua:" << lua_tostring(L, 1) << '\n';
        lua_pop(L, 1);
    }
    lua_getfield(L, -1, "num");
    int isnum;
    double num = lua_tonumberx(L, -1, &isnum);
    if (isnum == 1) {
        std::cout << "A.num = " << num << '\n';
    } else {
        std::cerr << "Field 'A.num' is not a number\n";
    }
    lua_pop(L, 1); // 弹出 'num'
    lua_pop(L, 1); // 弹出 'A'

    lua_close(L);
}

当然,这两个 lua_pop(L, 1) 可以合并成一个 lua_pop(L, 2)

2018-07-19 09:17:20