【问题标题】:How to manually destruct wrapped C++ class in Lua如何在 Lua 中手动破坏包装的 C++ 类
【发布时间】:2019-01-11 10:35:15
【问题描述】:

我想知道是否可以在 Lua 中手动破坏 C++ 类。

我尝试将nil 分配给一个类,但它似乎不起作用。

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, "local class = my.Class()\n"
                     "class = nil\n");
//    lua_close(L);
}

MyBindings.h

#pragma once
#include <iostream>

class Class
{
public:
    Class()
    {
        std::cout << "Class Constructed" << std::endl;
    };
    ~Class()
    {
        std::cout << "Class Destructed" << std::endl;
    };
};

MyBindings.i

%module my
%{
#include "MyBindings.h"
%}

%include "MyBindings.h"

我得到的结果:

Class Constructed

我期望的结果:

Class Constructed
Class Destructed

如果我调用lua_close(L); 或手动调用垃圾调用器lua_gc(L, LUA_GCCOLLECT, 0);,它会起作用

但我想了解是否有任何其他解决方案可以手动破坏 Lua 中的 C++ 类。

【问题讨论】:

    标签: c++ lua swig


    【解决方案1】:

    我猜Class 在你的程序中包装了某种资源,你想回收内存。为此,您可以模仿std::fstream 的行为。您可以随时通过调用close() 方法回收资源。如果你没有显式调用close(),析构函数会为你调用它。但是,这需要您对对象中的有效状态进行编码。我使用一个布尔值来做到这一点,在任何访问之前都必须对其进行检查。

    我假设您只是为了演示而省略了lua_close(L),但您不应该在未关闭 Lua 状态的情况下退出程序。否则可能不会调用终结器。例如,在未调用 lua_close(L) 的情况下突然退出时,缓冲的内容可能不会写入文件。

    MyBindings.i

    %module my
    %{
    #include "MyBindings.h"
    %}
    
    %include "MyBindings.h"
    

    MyBindings.h

    #pragma once
    #include <iostream>
    #include <stdexcept>
    
    class Class {
        bool m_valid{true};
    
    public:
        Class() { std::cout << "Class Constructed" << std::endl; }
    
        void action() {
            if (!m_valid) {
                throw std::runtime_error("Use after free");
            }
            // do something
        }
    
        void close() {
            std::cout << "Class Destructed" << std::endl;
            m_valid = false;
        }
    
        ~Class() {
            if (m_valid) {
                close();
            }
        }
    };
    

    Main.cpp

    #include <iostream>
    #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);
        if (luaL_dostring(L, "local class = my.Class()\n"
                             "class:close()\n") != 0) {
            std::cerr << lua_tostring(L, -1) << '\n';
            lua_pop(L, 1);
        }
        std::cout << "Closing...\n";
        lua_close(L);
    }
    

    调用示例:

    $ swig -c++ -lua MyBindings.i
    $ clang++ -Wall -Wextra -Wpedantic -std=c++11 -I /usr/include/lua5.2/ Main.cpp MyBindings_wrap.cxx -llua5.2
    $ ./a.out 
    Class Constructed
    Class Destructed
    Closing...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-28
      • 2020-11-14
      • 2014-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-29
      • 1970-01-01
      相关资源
      最近更新 更多