如何销毁C++;在package.preload函数中初始化 我使用Lua中的C++类,用SWIG。
由于我使用的是单个如何销毁C++;在package.preload函数中初始化 我使用Lua中的C++类,用SWIG。,c++,class,lua,swig,destructor,C++,Class,Lua,Swig,Destructor,由于我使用的是单个Lua\u状态,因此我希望能够在Lua脚本的特定块中释放变量,而无需调用Lua\u close(L) 我决定使用package.preload['name']以便在需要时使用require'name'从其他块访问块 我被告知在我执行以下操作后,package.preload函数中的变量将被释放: package.preload['name'] = nil package.loaded['name'] = nil 但是,我的自定义C++类似乎在此后也没有被破坏。 下面是我的完整
Lua\u状态
,因此我希望能够在Lua脚本的特定块中释放变量,而无需调用Lua\u close(L)
我决定使用package.preload['name']
以便在需要时使用require'name'
从其他块访问块
我被告知在我执行以下操作后,package.preload
函数中的变量将被释放:
package.preload['name'] = nil
package.loaded['name'] = nil
但是,我的自定义C++类似乎在此后也没有被破坏。
下面是我的完整示例代码: 在Main.cpp中
#include "Main.h"
int main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
luaopen_my(L);
lua_settop(L, 0);
luaL_dostring(L, "package.preload['test'] = function ()\n"
"local test = {}\n"
"local class = my.Class()\n"
"return test\n"
"end\n");
luaL_dostring(L, "require 'test'");
luaL_dostring(L, "package.preload['test'] = nil\n"
"package.loaded['test'] = nil\n");
}
%module my
%{
#include "MyBindings.h"
%}
%include <stl.i>
%include <typemaps.i>
%include "MyBindings.h"
在Main.h中
#include "lua.hpp"
extern "C"
{
int luaopen_my(lua_State *L);
}
int main();
在MyBindings.h
#include "Main.h"
class Class
{
public:
Class()
{
std::cout << "Class Constructed" << std::endl;
};
~Class()
{
std::cout << "Class Destructed" << std::endl;
};
};
结果:
Class Constructed
为什么不调用类析构函数,以及如何正确地析构函数包中的类和变量。预加载函数?您总是可以通过t obj.~class()显式调用d'tor。
如果你在Lua包装中使用外部类,我不是SRE,他们可以遵循C++中存在的正确嵌套的Dor Tor范例。 < P>我不能重现你的问题,但是你的代码中还有其他缺点,尤其是缺少头标头。文件
Main.h
不是必需的,在MyBindings.h
文件中更是如此,因为它没有使用它。我不知道你在使用哪一个编译器,但是<代码>无效主()/<代码>不是有效的C++,标准规定。
Main.cpp
#include "lua.hpp"
extern "C" int luaopen_my(lua_State *L);
int main() {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
luaopen_my(L);
lua_settop(L, 0);
luaL_dostring(L, "package.preload['test'] = function ()\n"
"local test = {}\n"
"local class = my.Class()\n"
"return test\n"
"end\n");
luaL_dostring(L, "require 'test'");
luaL_dostring(L, "package.preload['test'] = nil\n"
"package.loaded['test'] = nil\n");
lua_close(L);
}
#pragma once
#include <iostream>
class Class
{
public:
Class()
{
std::cout << "Class Constructed" << std::endl;
};
~Class()
{
std::cout << "Class Destructed" << std::endl;
};
};
%module my
%{
#include "MyBindings.h"
%}
%include "MyBindings.h"
MyBindings.h
#include "lua.hpp"
extern "C" int luaopen_my(lua_State *L);
int main() {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
luaopen_my(L);
lua_settop(L, 0);
luaL_dostring(L, "package.preload['test'] = function ()\n"
"local test = {}\n"
"local class = my.Class()\n"
"return test\n"
"end\n");
luaL_dostring(L, "require 'test'");
luaL_dostring(L, "package.preload['test'] = nil\n"
"package.loaded['test'] = nil\n");
lua_close(L);
}
#pragma once
#include <iostream>
class Class
{
public:
Class()
{
std::cout << "Class Constructed" << std::endl;
};
~Class()
{
std::cout << "Class Destructed" << std::endl;
};
};
%module my
%{
#include "MyBindings.h"
%}
%include "MyBindings.h"
调用示例:
$swig-c++-lua MyBindings.i
$clang++-Wall-Wextra-Wpedantic-I/usr/include/lua5.2-fPIC-sharedmybindings\u wrap.cxx-o my.so-llua5.2
$clangg++-Wall-Wextra-Wpedantic-I/usr/include/lua5.2-L。Main.cpp-l:my.so-llua5.2
$LD_库_路径=/a、 出去
类构造
类被破坏
您还应该注意,Lua是一种垃圾收集语言,即当垃圾收集器认为有必要时,析构函数将运行。您可以在C中使用或在Lua中使用手动运行垃圾收集器,但我强烈建议不要手动运行垃圾收集器,因为这通常会对性能产生负面影响(即使您手动运行垃圾收集器是为了提高性能)。只有当您在内存非常有限的环境中运行并且刚刚修剪了一个表或类似的东西时,才可以手动使用垃圾收集器 无论如何,我已经用上面编译的
my.so
模块为您准备了一个Lua示例
local my=require(“我的”)
本地x=my.Class()
打印(“信息:删除x”)
x=零
打印(“信息:收集垃圾”)
收集垃圾()
打印(“信息:完成:-”))
$lua5.2 test.lua
类构造
信息:删除x
信息:收集垃圾
类被破坏
信息:完成:-)
签名和<代码>外部“C++”<代码>声明<代码> main <代码>无效c++(1)…[…]它有一个声明类型的int类型的int […](2)“一个程序,声明……C语言链接的名字(在任何命名空间中)是不正确的。”“HenriMenke谢谢你指出。很抱歉,我在简化这个问题的代码时犯了一个错误。我编辑了我的代码。谢谢你的回答。你不能重现我的问题的原因是因为你有lua\u close(L)代码>这可能会释放所有分配的内存。我想做的只是在Lua脚本的特定块内(在代码>包内的自由变量。预加载< /COD>函数)中的自由内存。在C++中,手动不可能做到这一点吗?@ ZekLee首先,在退出程序之前,您应该总是调用<代码> LuaYOffCube(L)< /代码>。我在答案的第二部分向您解释了如何手动调用垃圾收集器。你的程序运行的机器有多少内存?@ZackLee你正在使用C-API,因此你可以等价地调用lua\u gc(L,lua\u GCCOLLECT,/*unused*/0)
为了节省字符串解析的成本,不,这不是解决内存问题的方法(如果您有任何问题,我非常怀疑)。调用collectgarbage()
也不能代替lua\u close(L)
!不要在没有许可的情况下退出您的程序!非常感谢,先生,我会给你一笔赏金。