问题描述
此问题与@Henri_Menke对此问题的回答有关:如何在C ++中获取预加载的模块名称
This question is related to @Henri_Menke's answer from this question : How to get preloaded module name in C++
我正在尝试使用自己的版本覆盖require
函数,以便可以在Lua脚本中获取预加载的模块名称.
I'm trying to override the require
function with my own version so I can get the preloaded module name inside Lua script.
这是我的代码:
#include "lua.hpp"
void main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_settop(L, 0);
luaL_dostring(L, "local require_original = require\n"
"function require(name, ...)\n"
"current_module = name\n"
"require_original(name, ...)\n"
"current_module = nil\n"
"end\n"); //if I comment out this chunk, it works fine
luaL_dostring(L, "package.preload['test'] = function ()\n"
"local test = {}\n"
"print('While loading:', current_module)\n"
"function test.update() print('Updated!') end\n"
"return test\n"
"end\n");
lua_getglobal(L, "require");
lua_pushstring(L, "test");
if (lua_pcall(L, 1, LUA_MULTRET, 0))
{
std::cout << "Error: " << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1);
}
int top = lua_gettop(L);
lua_getfield(L, -1, "update"); //crashes here
if (lua_isfunction(L, -1))
{
lua_pushnil(L);
if (lua_pcall(L, 1, LUA_MULTRET, 0))
{
std::cout << "Error: " << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1);
}
}
lua_close(L);
}
但是,它在调用lua_getfield(L, -1, "update");
时崩溃.
However, it crashes when calling lua_getfield(L, -1, "update");
.
当我注释掉Lua脚本的第一个块(第一个luaL_dostring
)时,它不再崩溃.
And it no longer crashes when I comment out the first chunk of Lua script(first luaL_dostring
).
如果我使用自己的require
版本,我不明白为什么它会崩溃.
I don't understand why it crashes if I use my own version of require
.
我该如何解决?
推荐答案
我忘记了从覆盖的require
函数返回模块表.抱歉.
I forgot to return the module table from overridden require
function. Sorry about that.
#include <iostream>
#include "lua.hpp"
int main() {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_settop(L, 0);
luaL_dostring(L, "local require_original = require\n"
"function require(name, ...)\n"
"current_module = name\n"
"local val = table.pack(require_original(name, ...))\n"
"current_module = nil\n"
"return table.unpack(val,1,val.n)\n"
"end\n"); //if I comment out this chunk, it works fine
luaL_dostring(L, "package.preload['test'] = function ()\n"
"local test = {}\n"
"print('While loading:', current_module)\n"
"function test.update() print('Updated!') end\n"
"return test\n"
"end\n");
lua_getglobal(L, "require");
lua_pushstring(L, "test");
if (lua_pcall(L, 1, LUA_MULTRET, 0))
{
std::cout << "Error: " << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1);
}
int top = lua_gettop(L);
lua_getfield(L, -1, "update"); //crashes here
if (lua_isfunction(L, -1))
{
lua_pushnil(L);
if (lua_pcall(L, 1, LUA_MULTRET, 0))
{
std::cout << "Error: " << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1);
}
}
lua_close(L);
}
$ clang++ -Wall -Wextra -Wpedantic -I /usr/include/lua5.2 test.cpp -llua5.2
test.cpp:28:9: warning: unused variable 'top' [-Wunused-variable]
int top = lua_gettop(L);
^
1 warning generated.
$ ./a.out
While loading: test
Updated!
这篇关于覆盖require后调用lua_getfield()时崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!