首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何卸载/销毁lua脚本?

如何卸载/销毁lua脚本?
EN

Stack Overflow用户
提问于 2020-08-17 02:59:07
回答 2查看 1.4K关注 0票数 1

我正在尝试制作一个非常简单的lua包装器,它可以用于加载和运行多个Lua脚本。我之所以担心,是因为我没有看到任何关于如何正确销毁/删除加载的脚本而不完全销毁lua_State本身的文档。

是否可以删除/卸载加载的lua脚本?这是不必要的,还是不断调用luaL_dofile会导致内存泄漏?

简化的问题..。如果我在同一个luaL_dofile对象上调用lua_State,这会导致内存泄漏或问题,还是lua在加载新脚本时在后端处理这个问题?

这是一个演示..。

代码语言:javascript
复制
lua_State* m_lua_state = luaL_newstate();
lua_gc(m_lua_state, LUA_GCSTOP, 0);
luaL_openlibs(m_lua_state);
lua_gc(m_lua_state, LUA_GCRESTART, 0);

for(int i = 0; i < 99999999; i++)
{
// Since I don't unload the previous file, does this cause a memory leak until  lua_close is called?
if (luaL_dofile(m_lua_state, file_path.c_str()) != LUA_OK)
{
   std::string error_msg = lua_tostring(m_lua_state, -1);
   std::cout << "Error: " << error_msg << std::endl;
   return false;
}
else
{
   lua_getglobal(m_lua_state, function_name.c_str());

   if (lua_isfunction(m_lua_state, -1))
   {
     int stack_size = lua_gettop(m_lua_state);

     int number_of_args = 0;
     if (lua_pcall(m_lua_state, number_of_args, 0, 0) != LUA_OK)
     {
        std::cout << "Error Calling Function In Script: " << file_path << "::" << function_name << " - " << lua_tostring(m_lua_state, -1) << std::endl;
     }
     int total_return_values = lua_gettop(m_lua_state) - stack_size;
  }
  else
  {
     std::cout << "Error Invalid Function In Script: " << file_path << "::" << function_name << std::endl;
  }
  }
}

lua_close(m_lua_state);
EN

回答 2

Stack Overflow用户

发布于 2020-08-17 05:44:46

如果卸载意味着撤消运行某些Lua代码的效果,那么除非在运行代码之前保存宝贵的状态,否则不能执行。这可以通过沙箱代码来完成。

如果您只想移除Lua表,请将对它的所有引用设置为零,并让该表自动或手动地被垃圾收集。

票数 2
EN

Stack Overflow用户

发布于 2020-08-17 22:39:43

当您加载一个lua文件时,您实际上正在执行它的代码。它不像dll或其他语言中的东西:

int luaL_dofile (lua_State *L,const char *filename);

加载并运行给定的文件。它被定义为以下宏:

如果您的文件是这样的:

代码语言:javascript
复制
function sayHello()
  print('Hello, world!')
end

然后加载文件将在全局对象上创建一个函数“sayHello”。如果您再次加载该文件,它将用新函数替换现有函数,并且不会出现内存泄漏。任何调用'sayHello‘的人都将调用全局对象上的新函数,除非他们保存了对原始函数的引用。代码通常会这样做,因为调用局部变量比调用全局函数要快一些。例如,如果另一个文件的顶部有local sayhi = sayHello,那么任何对'sayhi‘的调用都会调用原始函数。

如果您正在创建类并期望数据保持不变,那么在重新加载之前创建的任何对象(lua表)仍将引用旧类的元类。新类的代码不会自动应用于重新加载之前创建的类。

举一个LUA文档中的例子:

代码语言:javascript
复制
Account = {}

function Account:deposit (v)
  self.balance = self.balance + v
end

function Account:new (o)
  o = o or {}   -- create object if user does not provide one
  setmetatable(o, self)
  self.__index = self
  return o
end

a = Account:new{balance = 0}
a:deposit(100.00)

a现在是一个表,它的“余额”属性为100.00,一个元数据指向具有存款函数的帐户表。如果您更改了存款函数以打印余额并重新加载文件,它将替换全局“Account”表和函数,但是表“a”仍将保留原来的帐户表,因为它是可元的。因此,调用'a.deposit‘仍然不会打印值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63443978

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档