C++与Lua交互实例 -- 矩阵的加减乘除(版本二)

2023-05-16

C++与Lua交互实例 – 矩阵的加减乘除(版本二)

TIPS:关于使用矩阵的加减乘除测试C++与Lua的交互以及下面没讲述到的知识点可以阅读第一版:

https://blog.csdn.net/qq135595696/article/details/128960951

同时下面两个方式矩阵的数据都来源于C++端,只是第一种是在C++端进行结果比较展示,第二种方式(userdata)是在lua端进行结果比较展示。

下面C++端引入第三方开源库测试lua端矩阵的运算是否正确,参考链接如下:

http://eigen.tuxfamily.org/index.php?title=3.4

https://blog.csdn.net/qq_41854911/article/details/119814660

https://blog.csdn.net/thlzzz/article/details/110451022

CppToLua1

CppToLua.cpp

#include <iostream>
#include <vector>
#include <assert.h>
#include <Dense>
#include "lua.hpp"
using std::cout;
using std::endl;
using std::cin;

static int gs_Top = 0;
#define STACK_NUM(L) \
        gs_Top = lua_gettop(L); \
        std::cout<<"stack top:"<< gs_Top <<std::endl\

// 矩阵运算
enum class MATRIX_OPERATE {
    ADD,
    SUB,
    MUL,
    DIV,
    NONE
};


#define LUA_SCRIPT_PATH "matrix2.0.lua"
static std::vector<std::vector<double>> gs_mat1;
static std::vector<std::vector<double>> gs_mat2;


static bool OutPrint(const std::vector<std::vector<double>>& data) {
    for (int32_t i = 0; i < data.size(); i++) {
        for (int32_t j = 0; j < data[0].size(); j++)
            std::cout << " "<< data[i][j];
        std::cout << '\n';
    }
    std::cout << "......\n";
    return true;
}

static bool Init(lua_State* L) {
    assert(NULL != L);
    gs_mat1.clear();
    gs_mat2.clear();
    
    if (luaL_dofile(L, LUA_SCRIPT_PATH)) {
        printf("%s\n", lua_tostring(L, -1));
        return false;
    }
    return true;
}

static bool CreateLuaArr(lua_State* L, const std::vector<std::vector<double>>& data) {
    assert(NULL != L);
    //STACK_NUM(L);
    lua_newtable(L);
    for (int32_t i = 0; i < data.size(); i++) {
        lua_newtable(L);
        for (int32_t j = 0; j < data[0].size(); j++) {
            lua_pushnumber(L, data[i][j]);
            lua_rawseti(L, -2, j + 1);
        }
        lua_rawseti(L, -2, i + 1);
    }
    //STACK_NUM(L);
    return true;
}

static bool GetLuaArr(lua_State* L, std::vector<std::vector<double>>& outData) {
    assert(NULL != L);
    outData.clear();
    bool result = false;

    int32_t row = 0;
    int32_t col = 0;

    if (LUA_TTABLE != lua_type(L, -1)) {
        goto Exit;
    }

    if (LUA_TTABLE != lua_getfield(L, -1, "tbData")) {
        goto Exit;
    }

    lua_getfield(L, -2, "nRow");
    row = lua_tointeger(L, -1);
    lua_pop(L, 1);
    lua_getfield(L, -2, "nColumn");
    col = lua_tointeger(L, -1);
    lua_pop(L, 1);

    for (int32_t i = 0; i < row; i++) {
        lua_rawgeti(L, -1, i + 1);
        std::vector<double> data;
        for (int32_t j = 0; j < col; j++) {
            lua_rawgeti(L, -1, j + 1);
            data.push_back(lua_tonumber(L, -1));
            lua_pop(L, 1);
        }
        outData.push_back(data);
        lua_pop(L, 1);
    }
    
    //维持lua堆栈平衡
    lua_pop(L, 1);
    result = true;
Exit:
    return true;
}

static bool MatrixOperate(lua_State* L,
    std::vector<std::vector<double>>& outData, MATRIX_OPERATE type) {
    outData.clear();
    const char* funcName = NULL;
    bool        result   = false;
    switch (type) {
    case MATRIX_OPERATE::ADD:
        funcName = "MatrixAdd";
        break;
    case MATRIX_OPERATE::SUB:
        funcName = "MatrixSub";
        break;
    case MATRIX_OPERATE::MUL:
        funcName = "MatrixMul";
        break;
    case MATRIX_OPERATE::DIV:
        funcName = "MatrixDiv";
        break;
    case MATRIX_OPERATE::NONE:
        break;
    default:
        break;
    }

    lua_getglobal(L, funcName);
    luaL_checktype(L, -1, LUA_TFUNCTION);

    //添加形参
    CreateLuaArr(L, gs_mat1);
    CreateLuaArr(L, gs_mat2);

    //调用函数
    if (lua_pcall(L, 2, 1, 0)) {
        printf("error[%s]\n", lua_tostring(L, -1));
        goto Exit;
    }

    GetLuaArr(L, outData);
    result = true;
Exit:
    return result;
}

static bool APIMatrixOperate(const std::vector<std::vector<double>>& data1,
    const std::vector<std::vector<double>>& data2, MATRIX_OPERATE type, Eigen::MatrixXd& outResMat) {
    Eigen::MatrixXd mat1(data1.size(), data1[0].size());
    Eigen::MatrixXd mat2(data2.size(), data2[0].size());

    for (int i = 0; i < data1.size(); i++) {
        for (int j = 0; j < data1[0].size(); j++) {
            mat1(i, j) = data1[i][j];
        }
    }

    for (int i = 0; i < data2.size(); i++) {
        for (int j = 0; j < data2[0].size(); j++) {
            mat2(i, j) = data2[i][j];
        }
    }

    switch (type) {
    case MATRIX_OPERATE::ADD:
        outResMat = mat1 + mat2;
        break;
    case MATRIX_OPERATE::SUB:
        outResMat = mat1 - mat2;
        break;
    case MATRIX_OPERATE::MUL:
        outResMat = mat1 * mat2;
        break;
    case MATRIX_OPERATE::DIV:
        outResMat = mat1 * (mat2.inverse());
        break;
    case MATRIX_OPERATE::NONE:
        break;
    default:
        break;
    }

    return true;
}

static bool Run(lua_State* L) {
    assert(NULL != L);

    std::vector<std::vector<double>> addData;
    std::vector<std::vector<double>> subData;
    std::vector<std::vector<double>> mulData;
    std::vector<std::vector<double>> divData;

    Eigen::MatrixXd addApiData;
    Eigen::MatrixXd subApiData;
    Eigen::MatrixXd mulApiData;
    Eigen::MatrixXd divApiData;

    // 运算
    gs_mat1 = { { 1,2,3 }, { 4,5,6 } };
    gs_mat2 = { { 2,3,4 }, { 5,6,7 } };
    MatrixOperate(L, addData, MATRIX_OPERATE::ADD);
    APIMatrixOperate(gs_mat1, gs_mat2, MATRIX_OPERATE::ADD, addApiData);

    gs_mat1 = addData;
    gs_mat2 = { {1,1,1},{1,1,1} };
    MatrixOperate(L, subData, MATRIX_OPERATE::SUB);
    APIMatrixOperate(gs_mat1, gs_mat2, MATRIX_OPERATE::SUB, subApiData);

    gs_mat1 = { {1,2,3},{4,5,6} };
    gs_mat2 = { {7,8},{9,10},{11,12} };
    MatrixOperate(L, mulData, MATRIX_OPERATE::MUL);
    APIMatrixOperate(gs_mat1, gs_mat2, MATRIX_OPERATE::MUL, mulApiData);

    gs_mat1 = { {41,2,3},{424,5,6},{742,8,11} };
    gs_mat2 = { {1,2,1},{1,1,2},{2,1,1} };
    MatrixOperate(L, divData, MATRIX_OPERATE::DIV);
    APIMatrixOperate(gs_mat1, gs_mat2, MATRIX_OPERATE::DIV, divApiData);

    // 输出
    cout << "================加法:================" << endl;
    OutPrint(addData);
    cout << "正确答案:\n" << addApiData << endl;
    cout << "================减法:================" << endl;
    OutPrint(subData);
    cout << "正确答案:\n" << subApiData << endl;
    cout << "================乘法:================" << endl;
    OutPrint(mulData);
    cout << "正确答案:\n" << mulApiData << endl;
    cout << "================除法:================" << endl;
    OutPrint(divData);
    cout << "正确答案:\n" << divApiData << endl;
    return true;
}


static bool UnInit() {
    return true;
}


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

    if (Init(L)) {
        Run(L);
    }

    UnInit();

    lua_close(L);
	return 0;
}

matrix2.0.lua

local _class = {}

function class(super)
    local tbClassType = {}
    tbClassType.Ctor  = false
    tbClassType.super = super
    tbClassType.New   = function(...)
        local tbObj   = {}
        do
            local funcCreate
            funcCreate = function(tbClass,...)
                if tbClass.super then
                    funcCreate(tbClass.super,...)
                end
                
                if tbClass.Ctor then
                    tbClass.Ctor(tbObj,...)
                end
            end
            funcCreate(tbClassType,...)
        end
        -- 防止调用Ctor初始化时,在Ctor内部设置了元表的情况发生
        if getmetatable(tbObj) then
            getmetatable(tbObj).__index = _class[tbClassType] 
        else
            setmetatable(tbObj, { __index = _class[tbClassType] })
        end
        return tbObj
    end

    local vtbl          = {} 
    _class[tbClassType] = vtbl

    setmetatable(tbClassType, { __newindex = 
        function(tb,k,v)
            vtbl[k] = v
        end
    })

    if super then
        setmetatable(vtbl, { __index = 
            function(tb,k)
                local varRet = _class[super][k]
                vtbl[k]      = varRet
                return varRet
            end
        })
    end
    return tbClassType
end





Matrix = class()

function Matrix:Ctor(data)
    self.tbData = data
    self.nRow   = #data
    if self.nRow > 0 then
        self.nColumn = (#data[1])
    else
        self.nColumn = 0
    end
    -- print("row:",self.nRow," col:",self.nColumn)

    setmetatable(self,{
        __add = function(tbSource, tbDest)
            assert(tbSource,"tbSource not exist")
            assert(tbDest,  "tbDest not exist")
            local tbRes = Matrix.New({})
            -- print(tbSource,tbDest)
            -- print("tbSource:",tbSource.nRow,tbSource.nColumn)
            -- tbSource:Print()
            -- print("tbDest:",tbDest.nRow,tbDest.nColumn)
            -- tbDest:Print()
            if tbSource.nRow ~= tbDest.nRow 
                or tbSource.nColumn ~= tbDest.nColumn then
                print("row or column not equal...")
                return tbRes
            else
                for rowKey,rowValue in ipairs(tbSource.tbData) do
                    for colKey,colValue in ipairs(tbSource.tbData[rowKey]) do
                        if tbRes.tbData[rowKey] == nil then
                            tbRes.tbData[rowKey] = {}
                        end
                        
                        if tbRes.tbData[rowKey][colKey] == nil then
                            tbRes.tbData[rowKey][colKey] = 0
                        end

                        tbRes.tbData[rowKey][colKey] = 
                            tbSource.tbData[rowKey][colKey] + tbDest.tbData[rowKey][colKey]
                    end
                end 
                tbRes.nRow    = tbSource.nRow
                tbRes.nColumn = tbSource.nColumn
                return tbRes
            end
        end,
    
        __sub = function(tbSource, tbDest)
            assert(tbSource,"tbSource not exist")
            assert(tbDest,  "tbDest not exist")
            local tbRes = Matrix.New({})
            if tbSource.nRow ~= tbDest.nRow 
                or tbSource.nColumn ~= tbDest.nColumn then
                print("row or column not equal...")
                return tbRes
            else
                for rowKey,rowValue in ipairs(tbSource.tbData) do
                    for colKey,colValue in ipairs(tbSource.tbData[rowKey]) do
                        if tbRes.tbData[rowKey] == nil then
                            tbRes.tbData[rowKey] = {}
                        end
                        
                        if tbRes.tbData[rowKey][colKey] == nil then
                            tbRes.tbData[rowKey][colKey] = 0
                        end

                        tbRes.tbData[rowKey][colKey] = 
                            tbSource.tbData[rowKey][colKey] - tbDest.tbData[rowKey][colKey]
                    end
                end 
                tbRes.nRow    = tbSource.nRow
                tbRes.nColumn = tbSource.nColumn
                return tbRes
            end
        end,
    
        __mul = function(tbSource, tbDest)
            return self:_MartixMul(tbSource, tbDest)
        end,
    
        __div = function(tbSource, tbDest)
            assert(tbSource,"tbSource not exist")
            assert(tbDest,  "tbDest not exist")
            
            local nDet = self:_GetDetValue(tbDest)
            if nDet == 0 then
                print("matrix no inverse matrix...")
                return nil
            end
            -- print("det ",nDet)
            local tbInverseDest = self:_MatrixNumMul(self:_GetCompanyMatrix(tbDest), 1 / nDet)
            -- self:_GetCompanyMatrix(tbDest):Print()
            -- print(nDet)
            -- tbInverseDest:Print()
            return self:_MartixMul(tbSource, tbInverseDest)
        end
    }
)


end

function Matrix:Print()
    for rowKey,rowValue in ipairs(self.tbData) do
        for colKey,colValue in ipairs(self.tbData[rowKey]) do
            io.write(self.tbData[rowKey][colKey],',')
        end
        print('')
    end
end

-- 加
function Matrix:Add(matrix)
    return self + matrix
end

-- 减
function Matrix:Sub(matrix)
    return self - matrix
end

-- 乘
function Matrix:Mul(matrix)
    return self * matrix
end

-- 除
function Matrix:Div(matrix)
    return self / matrix
end


-- 切割,切去第rowIndex以及第colIndex列
function Matrix:_CutoffMatrix(tbMatrix, rowIndex, colIndex)
    assert(tbMatrix,"tbMatrix not exist")
    assert(rowIndex >= 1,"rowIndex < 1")
    assert(colIndex >= 1,"colIndex < 1")
    local tbRes   = Matrix.New({})
    tbRes.nRow    = tbMatrix.nRow    - 1
    tbRes.nColumn = tbMatrix.nColumn - 1
    for i = 1, tbMatrix.nRow - 1 do
        for j = 1, tbMatrix.nColumn - 1 do
            if tbRes.tbData[i] == nil then
                tbRes.tbData[i] = {}
            end
            
            local nRowDir = 0
            local nColDir = 0
            if i >= rowIndex then
                nRowDir = 1
            end

            if j >= colIndex then
                nColDir = 1
            end

            tbRes.tbData[i][j] = tbMatrix.tbData[i + nRowDir][j + nColDir]
        end
    end
    return tbRes
end

-- 获取矩阵的行列式对应的值
function Matrix:_GetDetValue(tbMatrix)
    assert(tbMatrix,"tbMatrix not exist")
    -- 当矩阵为一阶矩阵时,直接返回A中唯一的元素
    if tbMatrix.nRow == 1 then
        return tbMatrix.tbData[1][1]
    end

    local nAns = 0
    for i = 1, tbMatrix.nColumn do
        local nFlag = -1
        if i % 2 ~= 0 then
            nFlag = 1
        end

        nAns = 
            nAns + tbMatrix.tbData[1][i] * 
                self:_GetDetValue(self:_CutoffMatrix(tbMatrix, 1, i)) * nFlag
        -- print("_GetDetValue nflag:",nFlag)
    end
    return nAns
end


-- 获取矩阵的伴随矩阵
function Matrix:_GetCompanyMatrix(tbMatrix)
    assert(tbMatrix,"tbMatrix not exist")
    local tbRes   = Matrix.New({})
    -- 伴随矩阵与原矩阵存在转置关系
    tbRes.nRow    = tbMatrix.nColumn
    tbRes.nColumn = tbMatrix.nRow

    for i = 1, tbMatrix.nRow do
        for j = 1, tbMatrix.nColumn do
            local nFlag = 1
            if ((i + j) % 2) ~= 0 then
                nFlag = -1
            end       
            
            if tbRes.tbData[j] == nil then
                tbRes.tbData[j] = {}
            end
            -- print(Matrix:_GetDetValue(Matrix:_CutoffMatrix(tbMatrix, i, j)))
            -- Matrix:_CutoffMatrix(tbMatrix, i, j):Print()
            -- print("---11----")

            tbRes.tbData[j][i] = 
                self:_GetDetValue(self:_CutoffMatrix(tbMatrix, i, j)) * nFlag
        end
    end
    return tbRes
end


-- 矩阵数乘
function Matrix:_MatrixNumMul(tbMatrix, num)
    for i = 1, tbMatrix.nRow do
        for j = 1, tbMatrix.nColumn do
            tbMatrix.tbData[i][j] = tbMatrix.tbData[i][j] * num
        end
    end
    return tbMatrix
end


-- 矩阵相乘
function Matrix:_MartixMul(tbSource, tbDest)
    assert(tbSource,"tbSource not exist")
    assert(tbDest,  "tbDest not exist")
    if tbSource.nColumn ~= tbDest.nRow then
        print("column not equal row...")
        return tbSource
    else
        local tbRes = Matrix.New({})
        for i = 1, tbSource.nRow do
            for j = 1, tbDest.nColumn do
                if tbRes.tbData[i] == nil then
                    tbRes.tbData[i] = {}
                end
                
                if tbRes.tbData[i][j] == nil then
                    tbRes.tbData[i][j] = 0
                end

                for k = 1, tbSource.nColumn do
                    tbRes.tbData[i][j] = 
                        tbRes.tbData[i][j] + (tbSource.tbData[i][k] * tbDest.tbData[k][j])
                end
            end
        end
        tbRes.nRow    = tbSource.nRow
        tbRes.nColumn = tbDest.nColumn
        return tbRes
    end
end



-- add
function MatrixAdd(data1, data2)
    assert(data1,"data1 not exist")
    assert(data2,"data2 not exist")
    local matrix1 = Matrix.New(data1)
    local matrix2 = Matrix.New(data2)
    return matrix1 + matrix2
end

-- sub
function MatrixSub(data1, data2)
    assert(data1,"data1 not exist")
    assert(data2,"data2 not exist")
    local matrix1 = Matrix.New(data1)
    local matrix2 = Matrix.New(data2)
    return matrix1 - matrix2
end

-- mul
function MatrixMul(data1, data2)
    assert(data1,"data1 not exist")
    assert(data2,"data2 not exist")
    local matrix1 = Matrix.New(data1)
    local matrix2 = Matrix.New(data2)
    return matrix1 * matrix2
end

-- div
function MatrixDiv(data1, data2)
    assert(data1,"data1 not exist")
    assert(data2,"data2 not exist")
    local matrix1 = Matrix.New(data1)
    local matrix2 = Matrix.New(data2)
    return matrix1 / matrix2
end

输出结果

效果图

CppToLua2

CppToLua.cpp

#include <iostream>
#include <Dense>
#include <vector>
#include "lua.hpp"
using std::cout;
using std::endl;
using std::cin;

#define CPP_MATRIX      "CPP_MATRIX"
#define LUA_SCRIPT_PATH "matrix2.0-lua.lua"


static int gs_Top = 0;
#define STACK_NUM(L) \
        gs_Top = lua_gettop(L); \
        std::cout<<"stack top:"<< gs_Top <<std::endl\

// 矩阵运算
enum class MATRIX_OPERATE {
    ADD,
    SUB,
    MUL,
    DIV,
    NONE
};

static std::vector<std::vector<double>> gs_mat1;
static std::vector<std::vector<double>> gs_mat2;

extern "C" {
    static int CreateMatrix(lua_State* L) {
        Eigen::MatrixXd** pp =
            (Eigen::MatrixXd**)lua_newuserdata(L, sizeof(Eigen::MatrixXd*));
        *pp = new Eigen::MatrixXd();
        luaL_setmetatable(L, CPP_MATRIX);
        return 1;
    }

    static int InitMatrix(lua_State* L) {
        assert(NULL != L);
        int32_t row = 0;
        int32_t col = 0;

        row = luaL_len(L, -1);
        lua_rawgeti(L, -1, 1);
        col = luaL_len(L, -1);
        lua_pop(L, 1);

        Eigen::MatrixXd** pp =
            (Eigen::MatrixXd**)luaL_checkudata(L, 1, CPP_MATRIX);
        (*pp)->resize(row, col);

        for (int32_t i = 0; i < row; i++) {
            lua_rawgeti(L, -1, i + 1);
            for (int32_t j = 0; j < col; j++) {
                lua_rawgeti(L, -1, j + 1);
                (**pp)(i, j) = lua_tonumber(L, -1);
                lua_pop(L, 1);
            }
            lua_pop(L, 1);
        }

        lua_pop(L, 2);
        return 0;
    }

    static int UnInitMatrix(lua_State* L) {
        Eigen::MatrixXd** pp = 
            (Eigen::MatrixXd**)luaL_checkudata(L, 1, CPP_MATRIX);
        std::cout << "auto gc" << std::endl;
        if (*pp) {
            delete *pp;
        }
        return 0;
    }

    static int AddMatrix(lua_State* L) {
        //STACK_NUM(L);
        Eigen::MatrixXd** pp1 = 
            (Eigen::MatrixXd**)luaL_checkudata(L, 1, CPP_MATRIX);
        Eigen::MatrixXd** pp2 = 
            (Eigen::MatrixXd**)luaL_checkudata(L, 2, CPP_MATRIX);

        Eigen::MatrixXd** pp =
            (Eigen::MatrixXd**)lua_newuserdata(L, sizeof(Eigen::MatrixXd*));
        *pp = new Eigen::MatrixXd();     //该部分内存由C++分配
        **pp = (**pp1) + (**pp2);
        luaL_setmetatable(L, CPP_MATRIX);
        //STACK_NUM(L);
        return 1;
    }

    static int SubMatrix(lua_State* L) {
        //STACK_NUM(L);
        Eigen::MatrixXd** pp1 =
            (Eigen::MatrixXd**)luaL_checkudata(L, 1, CPP_MATRIX);
        Eigen::MatrixXd** pp2 =
            (Eigen::MatrixXd**)luaL_checkudata(L, 2, CPP_MATRIX);

        Eigen::MatrixXd** pp =
            (Eigen::MatrixXd**)lua_newuserdata(L, sizeof(Eigen::MatrixXd*));
        *pp = new Eigen::MatrixXd();     //该部分内存由C++分配
        **pp = (**pp1) - (**pp2);
        luaL_setmetatable(L, CPP_MATRIX);
        //STACK_NUM(L);
        return 1;
    }

    static int MulMatrix(lua_State* L) {
        //STACK_NUM(L);
        Eigen::MatrixXd** pp1 =
            (Eigen::MatrixXd**)luaL_checkudata(L, 1, CPP_MATRIX);
        Eigen::MatrixXd** pp2 =
            (Eigen::MatrixXd**)luaL_checkudata(L, 2, CPP_MATRIX);

        Eigen::MatrixXd** pp =
            (Eigen::MatrixXd**)lua_newuserdata(L, sizeof(Eigen::MatrixXd*));
        *pp = new Eigen::MatrixXd();     //该部分内存由C++分配
        **pp = (**pp1) * (**pp2);
        luaL_setmetatable(L, CPP_MATRIX);
        //STACK_NUM(L);
        return 1;
    }

    static int DivMatrix(lua_State* L) {
        //STACK_NUM(L);
        Eigen::MatrixXd** pp1 =
            (Eigen::MatrixXd**)luaL_checkudata(L, 1, CPP_MATRIX);
        Eigen::MatrixXd** pp2 =
            (Eigen::MatrixXd**)luaL_checkudata(L, 2, CPP_MATRIX);

        Eigen::MatrixXd** pp =
            (Eigen::MatrixXd**)lua_newuserdata(L, sizeof(Eigen::MatrixXd*));
        *pp = new Eigen::MatrixXd();     //该部分内存由C++分配
        **pp = (**pp1) * ((**pp2).inverse());
        luaL_setmetatable(L, CPP_MATRIX);
        //STACK_NUM(L);
        return 1;
    }

    static int PrintMatrix(lua_State* L) {
        Eigen::MatrixXd** pp = 
            (Eigen::MatrixXd**)luaL_checkudata(L, 1, CPP_MATRIX);
        std::cout << "正确答案:\n" << **pp << std::endl;
        return 0;
    }
}


static const luaL_Reg MatrixFuncs[] = {
    {"InitMatrix", InitMatrix  },
    {"__gc",       UnInitMatrix},
    {"__add",      AddMatrix   },
    {"__sub",      SubMatrix   },
    {"__mul",      MulMatrix   },
    {"__div",      DivMatrix   },
    {"PrintMatrix",PrintMatrix },
    {NULL,         NULL        }
};

extern "C" {
    static bool CreateMatrixMetaTable(lua_State* L) {
        luaL_newmetatable(L, CPP_MATRIX);
        lua_pushvalue(L, -1);
        lua_setfield(L, -2, "__index");
        luaL_setfuncs(L, MatrixFuncs, 0);
        //STACK_NUM(L);
        lua_pop(L, 1);
        return true;
    }
}

bool CreateLuaArr(lua_State* L, const std::vector<std::vector<double>>& data) {
    assert(NULL != L);
    //STACK_NUM(L);
    lua_newtable(L);
    for (int32_t i = 0; i < data.size(); i++) {
        lua_newtable(L);
        for (int32_t j = 0; j < data[0].size(); j++) {
            lua_pushnumber(L, data[i][j]);
            lua_rawseti(L, -2, j + 1);
        }
        lua_rawseti(L, -2, i + 1);
    }
    //STACK_NUM(L);
    return true;
}


bool MatrixOperate(lua_State* L, MATRIX_OPERATE type) {
    const char* funcName = NULL;
    bool        result = false;
    switch (type) {
    case MATRIX_OPERATE::ADD:
        funcName = "MatrixAdd";
        break;
    case MATRIX_OPERATE::SUB:
        funcName = "MatrixSub";
        break;
    case MATRIX_OPERATE::MUL:
        funcName = "MatrixMul";
        break;
    case MATRIX_OPERATE::DIV:
        funcName = "MatrixDiv";
        break;
    case MATRIX_OPERATE::NONE:
        break;
    default:
        break;
    }

    lua_getglobal(L, funcName);
    luaL_checktype(L, -1, LUA_TFUNCTION);

    //添加形参
    CreateLuaArr(L, gs_mat1);
    CreateLuaArr(L, gs_mat2);

    //调用函数
    if (lua_pcall(L, 2, 0, 0)) {
        printf("error[%s]\n", lua_tostring(L, -1));
        goto Exit;
    }

    result = true;
Exit:
    return result;
}


bool Init(lua_State *L) {
    //构造一张全局元表,名为CPP_MATRIX
    CreateMatrixMetaTable(L);

    //注册第三方API构造对象方法
    lua_pushcfunction(L, CreateMatrix);
    lua_setglobal(L, "CreateMatrix");

    if (luaL_dofile(L, LUA_SCRIPT_PATH)) {
        printf("%s\n", lua_tostring(L, -1));
    }
    return true;
}

bool Run(lua_State* L) {
    assert(NULL != L);

    // 运算
    gs_mat1 = { { 1,2,3 }, { 4,5,6 } };
    gs_mat2 = { { 2,3,4 }, { 5,6,7 } };
    MatrixOperate(L, MATRIX_OPERATE::ADD);

    gs_mat1 = { { 1,2,3 }, { 4,5,6 } };
    gs_mat2 = { { 1,1,1 }, { 1,1,1 } };
    MatrixOperate(L, MATRIX_OPERATE::SUB);

    gs_mat1 = { {1,2,3},{4,5,6} };
    gs_mat2 = { {7,8},{9,10},{11,12} };
    MatrixOperate(L, MATRIX_OPERATE::MUL);

    gs_mat1 = { {41,2,3},{424,5,6},{742,8,11} };
    gs_mat2 = { {1,2,1},{1,1,2},{2,1,1} };
    MatrixOperate(L, MATRIX_OPERATE::DIV);
    return true;
}

bool UnInit() {

    return true;
}

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

    luaL_openlibs(L);

    if (Init(L)) {
        Run(L);
    }

    UnInit();

    lua_close(L);
	return 0;
}

matrix2.0-lua.lua

local _class = {}

function class(super)
    local tbClassType = {}
    tbClassType.Ctor  = false
    tbClassType.super = super
    tbClassType.New   = function(...)
        local tbObj   = {}
        do
            local funcCreate
            funcCreate = function(tbClass,...)
                if tbClass.super then
                    funcCreate(tbClass.super,...)
                end
                
                if tbClass.Ctor then
                    tbClass.Ctor(tbObj,...)
                end
            end
            funcCreate(tbClassType,...)
        end
        -- 防止调用Ctor初始化时,在Ctor内部设置了元表的情况发生
        if getmetatable(tbObj) then
            getmetatable(tbObj).__index = _class[tbClassType] 
        else
            setmetatable(tbObj, { __index = _class[tbClassType] })
        end
        return tbObj
    end

    local vtbl          = {} 
    _class[tbClassType] = vtbl

    setmetatable(tbClassType, { __newindex = 
        function(tb,k,v)
            vtbl[k] = v
        end
    })

    if super then
        setmetatable(vtbl, { __index = 
            function(tb,k)
                local varRet = _class[super][k]
                vtbl[k]      = varRet
                return varRet
            end
        })
    end
    return tbClassType
end





Matrix = class()

function Matrix:Ctor(data)
    self.tbData = data
    self.nRow   = #data
    if self.nRow > 0 then
        self.nColumn = (#data[1])
    else
        self.nColumn = 0
    end
    -- print("row:",self.nRow," col:",self.nColumn)

    setmetatable(self,{
        __add = function(tbSource, tbDest)
            assert(tbSource,"tbSource not exist")
            assert(tbDest,  "tbDest not exist")
            local tbRes = Matrix.New({})
            -- print(tbSource,tbDest)
            -- print("tbSource:",tbSource.nRow,tbSource.nColumn)
            -- tbSource:Print()
            -- print("tbDest:",tbDest.nRow,tbDest.nColumn)
            -- tbDest:Print()
            if tbSource.nRow ~= tbDest.nRow 
                or tbSource.nColumn ~= tbDest.nColumn then
                print("row or column not equal...")
                return tbRes
            else
                for rowKey,rowValue in ipairs(tbSource.tbData) do
                    for colKey,colValue in ipairs(tbSource.tbData[rowKey]) do
                        if tbRes.tbData[rowKey] == nil then
                            tbRes.tbData[rowKey] = {}
                        end
                        
                        if tbRes.tbData[rowKey][colKey] == nil then
                            tbRes.tbData[rowKey][colKey] = 0
                        end

                        tbRes.tbData[rowKey][colKey] = 
                            tbSource.tbData[rowKey][colKey] + tbDest.tbData[rowKey][colKey]
                    end
                end 
                tbRes.nRow    = tbSource.nRow
                tbRes.nColumn = tbSource.nColumn
                return tbRes
            end
        end,
    
        __sub = function(tbSource, tbDest)
            assert(tbSource,"tbSource not exist")
            assert(tbDest,  "tbDest not exist")
            local tbRes = Matrix.New({})
            if tbSource.nRow ~= tbDest.nRow 
                or tbSource.nColumn ~= tbDest.nColumn then
                print("row or column not equal...")
                return tbRes
            else
                for rowKey,rowValue in ipairs(tbSource.tbData) do
                    for colKey,colValue in ipairs(tbSource.tbData[rowKey]) do
                        if tbRes.tbData[rowKey] == nil then
                            tbRes.tbData[rowKey] = {}
                        end
                        
                        if tbRes.tbData[rowKey][colKey] == nil then
                            tbRes.tbData[rowKey][colKey] = 0
                        end

                        tbRes.tbData[rowKey][colKey] = 
                            tbSource.tbData[rowKey][colKey] - tbDest.tbData[rowKey][colKey]
                    end
                end 
                tbRes.nRow    = tbSource.nRow
                tbRes.nColumn = tbSource.nColumn
                return tbRes
            end
        end,
    
        __mul = function(tbSource, tbDest)
            return self:_MartixMul(tbSource, tbDest)
        end,
    
        __div = function(tbSource, tbDest)
            assert(tbSource,"tbSource not exist")
            assert(tbDest,  "tbDest not exist")
            
            local nDet = self:_GetDetValue(tbDest)
            if nDet == 0 then
                print("matrix no inverse matrix...")
                return nil
            end
            -- print("det ",nDet)
            local tbInverseDest = self:_MatrixNumMul(self:_GetCompanyMatrix(tbDest), 1 / nDet)
            -- self:_GetCompanyMatrix(tbDest):Print()
            -- print(nDet)
            -- tbInverseDest:Print()
            return self:_MartixMul(tbSource, tbInverseDest)
        end
    }
)

end

function Matrix:Print()
    for rowKey,rowValue in ipairs(self.tbData) do
        for colKey,colValue in ipairs(self.tbData[rowKey]) do
            io.write(self.tbData[rowKey][colKey],',')
        end
        print('')
    end
end

-- 加
function Matrix:Add(matrix)
    return self + matrix
end

-- 减
function Matrix:Sub(matrix)
    return self - matrix
end

-- 乘
function Matrix:Mul(matrix)
    return self * matrix
end

-- 除
function Matrix:Div(matrix)
    return self / matrix
end


-- 切割,切去第rowIndex以及第colIndex列
function Matrix:_CutoffMatrix(tbMatrix, rowIndex, colIndex)
    assert(tbMatrix,"tbMatrix not exist")
    assert(rowIndex >= 1,"rowIndex < 1")
    assert(colIndex >= 1,"colIndex < 1")
    local tbRes   = Matrix.New({})
    tbRes.nRow    = tbMatrix.nRow    - 1
    tbRes.nColumn = tbMatrix.nColumn - 1
    for i = 1, tbMatrix.nRow - 1 do
        for j = 1, tbMatrix.nColumn - 1 do
            if tbRes.tbData[i] == nil then
                tbRes.tbData[i] = {}
            end
            
            local nRowDir = 0
            local nColDir = 0
            if i >= rowIndex then
                nRowDir = 1
            end

            if j >= colIndex then
                nColDir = 1
            end

            tbRes.tbData[i][j] = tbMatrix.tbData[i + nRowDir][j + nColDir]
        end
    end
    return tbRes
end

-- 获取矩阵的行列式对应的值
function Matrix:_GetDetValue(tbMatrix)
    assert(tbMatrix,"tbMatrix not exist")
    -- 当矩阵为一阶矩阵时,直接返回A中唯一的元素
    if tbMatrix.nRow == 1 then
        return tbMatrix.tbData[1][1]
    end

    local nAns = 0
    for i = 1, tbMatrix.nColumn do
        local nFlag = -1
        if i % 2 ~= 0 then
            nFlag = 1
        end

        nAns = 
            nAns + tbMatrix.tbData[1][i] * 
                self:_GetDetValue(self:_CutoffMatrix(tbMatrix, 1, i)) * nFlag
        -- print("_GetDetValue nflag:",nFlag)
    end
    return nAns
end


-- 获取矩阵的伴随矩阵
function Matrix:_GetCompanyMatrix(tbMatrix)
    assert(tbMatrix,"tbMatrix not exist")
    local tbRes   = Matrix.New({})
    -- 伴随矩阵与原矩阵存在转置关系
    tbRes.nRow    = tbMatrix.nColumn
    tbRes.nColumn = tbMatrix.nRow

    for i = 1, tbMatrix.nRow do
        for j = 1, tbMatrix.nColumn do
            local nFlag = 1
            if ((i + j) % 2) ~= 0 then
                nFlag = -1
            end       
            
            if tbRes.tbData[j] == nil then
                tbRes.tbData[j] = {}
            end
            -- print(Matrix:_GetDetValue(Matrix:_CutoffMatrix(tbMatrix, i, j)))
            -- Matrix:_CutoffMatrix(tbMatrix, i, j):Print()
            -- print("---11----")

            tbRes.tbData[j][i] = 
                self:_GetDetValue(self:_CutoffMatrix(tbMatrix, i, j)) * nFlag
        end
    end
    return tbRes
end


-- 矩阵数乘
function Matrix:_MatrixNumMul(tbMatrix, num)
    for i = 1, tbMatrix.nRow do
        for j = 1, tbMatrix.nColumn do
            tbMatrix.tbData[i][j] = tbMatrix.tbData[i][j] * num
        end
    end
    return tbMatrix
end


-- 矩阵相乘
function Matrix:_MartixMul(tbSource, tbDest)
    assert(tbSource,"tbSource not exist")
    assert(tbDest,  "tbDest not exist")
    if tbSource.nColumn ~= tbDest.nRow then
        print("column not equal row...")
        return tbSource
    else
        local tbRes = Matrix.New({})
        for i = 1, tbSource.nRow do
            for j = 1, tbDest.nColumn do
                if tbRes.tbData[i] == nil then
                    tbRes.tbData[i] = {}
                end
                
                if tbRes.tbData[i][j] == nil then
                    tbRes.tbData[i][j] = 0
                end

                for k = 1, tbSource.nColumn do
                    tbRes.tbData[i][j] = 
                        tbRes.tbData[i][j] + (tbSource.tbData[i][k] * tbDest.tbData[k][j])
                end
            end
        end
        tbRes.nRow    = tbSource.nRow
        tbRes.nColumn = tbDest.nColumn
        return tbRes
    end
end



-- add
function MatrixAdd(data1, data2)
    assert(data1,"data1 not exist")
    assert(data2,"data2 not exist")
    local matrix1 = Matrix.New(data1)
    local matrix2 = Matrix.New(data2)
    local matrix3 = matrix1 + matrix2
    print("===========加法===========")
    matrix3:Print()

    local cppMatrix1 = CreateMatrix()
    cppMatrix1:InitMatrix(data1)
    local cppMatrix2 = CreateMatrix()
    cppMatrix2:InitMatrix(data2)
    local cppMatrix3 = cppMatrix1 + cppMatrix2
    cppMatrix3:PrintMatrix()
end

-- sub
function MatrixSub(data1, data2)
    assert(data1,"data1 not exist")
    assert(data2,"data2 not exist")
    local matrix1 = Matrix.New(data1)
    local matrix2 = Matrix.New(data2)
    local matrix3 = matrix1 - matrix2
    print("===========减法===========")
    matrix3:Print()

    local cppMatrix1 = CreateMatrix()
    cppMatrix1:InitMatrix(data1)
    local cppMatrix2 = CreateMatrix()
    cppMatrix2:InitMatrix(data2)
    local cppMatrix3 = cppMatrix1 - cppMatrix2
    cppMatrix3:PrintMatrix()
end

-- mul
function MatrixMul(data1, data2)
    assert(data1,"data1 not exist")
    assert(data2,"data2 not exist")
    local matrix1 = Matrix.New(data1)
    local matrix2 = Matrix.New(data2)
    local matrix3 = matrix1 * matrix2
    print("===========乘法===========")
    matrix3:Print()

    local cppMatrix1 = CreateMatrix()
    cppMatrix1:InitMatrix(data1)
    local cppMatrix2 = CreateMatrix()
    cppMatrix2:InitMatrix(data2)
    local cppMatrix3 = cppMatrix1 * cppMatrix2
    cppMatrix3:PrintMatrix()
end

-- div
function MatrixDiv(data1, data2)
    assert(data1,"data1 not exist")
    assert(data2,"data2 not exist")
    local matrix1 = Matrix.New(data1)
    local matrix2 = Matrix.New(data2)
    local matrix3 = matrix1 / matrix2
    print("===========除法===========")
    matrix3:Print()

    local cppMatrix1 = CreateMatrix()
    cppMatrix1:InitMatrix(data1)
    local cppMatrix2 = CreateMatrix()
    cppMatrix2:InitMatrix(data2)
    local cppMatrix3 = cppMatrix1 / cppMatrix2
    cppMatrix3:PrintMatrix()
end

输出结果

效果图

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++与Lua交互实例 -- 矩阵的加减乘除(版本二) 的相关文章

  • 为Keil添加注释的快捷键

    Keil刚装上是没有注释快捷键的 xff0c 可以自己添加 xff0c Edit Configuration xff0c 然后选择 Shortcut Keys 标签页 xff0c 下拉找到 Comment Selection xff0c 然
  • C语言__attribute__的使用

    一 介绍 GNU C 的一大特色就是 attribute 机制 attribute 可以设置函数属性 xff08 Function Attribute xff09 变量属性 xff08 Variable Attribute xff09 和类
  • ros(30):while(ros::ok()){}理解与使用示例

    while ros ok 理解 while ros ok 是ros的一种循环模式 xff0c 和ros Rate loop rate ros spinOnce 等结合可以控制程序的执行顺序 ros Rate loop rate 10 设置循
  • Jetson TX2更换软件源

    TX2的软件源为国外服务器 xff0c 网速会很慢 xff0c 需要换国内的ARM源 备份 etc lib路径下的source list文件 xff0c 然后在终端 xff08 按ctrl 43 alt 43 T打开 xff09 执行以下命
  • 使用Dockerfile创建镜像

    Dockerfile是一个文本格式的配置文件 xff0c 可以使用Dockerfile来快速创建自定义的镜像 一 基本结构 Dockerfile由一行行命令语句组成 xff0c 并且支持以 开头的注释行 一般而言 xff0c Dockerf
  • 高质量嵌入式Linux C编程 第二章 数据 学习笔记

    一 什么是数据类型 xff1f 数据类型包含两方面的内容 xff0c 数据的表示和对数据加工的操作 数据的全部可能表示构成数据类型的值的集合 xff0c 数据全部合理的操作构成数据类型的操作集合 二 什么是变量 xff1f 其值在作用域内可
  • 高质量嵌入式Linux C编程 第三章 运算符、表达式学习

    一 运算符有哪几类 xff1f xff08 1 xff09 算数运算符 xff1a 43 43 43 七种 xff08 2 xff09 关系运算符 xff1a gt lt 61 61 gt 61 lt 61 xff01 61 六种 xff0
  • 设计一种可全向移动的球形机器人

    一 前言 之前在网上看到一种球形机器人 xff0c 觉得很有趣 xff0c 而且原理也比较简单 xff0c 大概就是把一辆小车放在一个透明的亚克力球中 xff0c 控制小车使球体滚动 xff0c 姿态控制算法与平衡小车类似 xff0c 然后
  • ROS-Python

    用python来编写ros话题 服务方面常用的几个点 xff1a 话题topic 1 初始化节点 rospy init node 34 节点名字 34 举例 xff1a rospy init node 34 test 34 anonymou
  • 关于SBUS信号在单片机中的一些个人理解

    最近一直在弄关于SBUS的编码与解码这方面的内容 xff0c 虽然网上资料很多 xff0c 但是网上资料太杂 xff0c 我找的一些资料可能是我理解的问题 xff0c 所以我摒弃了一些骚操作 xff0c 对于一些单片机学得不精的人来说 xf
  • C++中的指针

    以下为本人大一时阅读 C 43 43 Primer Plus 关于指针的章节所做的笔记 指针 一个函数只能返回一个值 xff0c 但是如果使用指针来传递变量 xff0c 则可以修改更多的值 xff0c 可以达到返回不止一个值的效果 用指针作
  • 四旋翼建模

    文章整理于 xff1a 共轴八旋翼无人飞行器姿态与航迹跟踪控制研究 彭程点击打开链接
  • 最新定时更新:Spring Cloud 各个版本整理汇总。最新为2022,Kilburn版本

    网址 xff1a https spring io 英文中文终结版本boot大版本boot代表说明Angel安吉尔SR61 2 X1 2 8GABrixton布里克斯顿SR71 3 X1 3 8GACamden卡梅登SR71 4 X1 4 2
  • 深度学习(23):SmoothL1Loss损失函数

    0 基本介绍 SmoothL1Loss是一种常用的损失函数 xff0c 通常用于回归任务中 xff0c 其相对于均方差 MSE 损失函数的优势在于对异常值 如过大或过小的离群点 的惩罚更小 xff0c 从而使模型更加健壮 SmoothL1L
  • Jetson Nano\NX\AGX 学习笔记

    Jetson Nano NX AGX 学习笔记 1 jetson平台安装pytorch torchvision2 yolov5模型部署deepstream x86 jetson平台2 0 下载 96 deepstream6 1 96 2 1
  • jetson系列硬件性能对比

    参考 Jetson Modules https developer nvidia com embedded jetson modules 第一种 4G 价格 1000元 1x 4K30 2x1080p60 4x1080p30 4x720p6
  • 遍历_EPROCESS->ObjectTable->HandleTableList链表枚举进程

    include lt ntifs h gt include lt ntddk h gt UCHAR PsGetProcessImageFileName in PEPROCESS Process HANDLE PsGetProcessInhe
  • Ubunut18.04安装Autoware1.12

    官方提供了两种安装Autoware的方法 xff1a Docker和Source两种方式 下边以Ubuntu18 04环境为例 xff0c 记录Source的安装方法 1 配置要求 1 1硬件 1 2软件 Qt安装 qmake span c
  • PuTTY在远程连接服务器之后,经常会断线提示“Software caused connection abort”,而且经常在很短的时间内就失去连接

    解决方案如下 xff1a 第一步 xff1a 设置服务器 1 修改服务器中 etc ssh sshd config 文件 xff0c 将LoginGraceTime的值设为0 xff0c TCPKeepAlive 设为yes 2 servi
  • Go语言循环语句

    Go语言循环语句 资料参考至菜鸟教程 在不少实际问题中有许多具有规律性的重复操作 xff0c 因此在程序中就需要重复执行某些语句 以下为大多编程语言循环程序的流程图 xff1a Go语言提供了以下几种类型循环处理语句 xff1a 循环类型描

随机推荐

  • Lua 协同程序(coroutine)

    Lua 协同程序 coroutine 参考文章 xff1a 菜鸟教程 https zhuanlan zhihu com p 480357405 https zhuanlan zhihu com p 76249973 Lua 协同程序 cor
  • Lua 变量

    Lua 变量 参考至菜鸟教程 变量在使用前 xff0c 需要在代码中进行声明 xff0c 即创建该变量 变量需要标识类型是因为编译程序执行代码之前需要知道如何给语句变量开辟存储区 xff0c 用于存储变量的值 Lua变量有三种类型 xff1
  • Lua 函数 - 可变参数

    Lua 函数 可变参数 参考至菜鸟教程 Lua函数可以接收可变数目的参数 xff0c 和C语言类似 xff0c 在函数参数列表中使用三点 表示函数有可变的参数 span class token keyword function span s
  • Lua 运算符 - 较为特殊部分

    Lua 运算符 较为特殊部分 参考至菜鸟教程 算术运算符 操作符描述实例 乘幂A 2 输出结果 100 负号 A 输出结果 10 整除运算符 gt 61 lua5 3 5 2 输出结果 2 在 lua 中 xff0c 用作除法运算 xff0
  • python(9):python循环打印进度条

    1 while 循环 Python的while循环可以打印进度条 xff0c 可以使用tqdm这个库来实现 tqdm是一个用于在Python中添加进度条的库 xff0c 它可以很容易地集成到while循环中 下面是一个简单的示例 xff0c
  • 平衡车直立PID调节总结

    苦战一周 xff0c 终于使平衡小车站了起来 xff0c PID无疑是我从学习板子至今遇到最困难的东西了 xff0c 并不是说它原理有多么复杂 xff0c 只是想让小车的效果更佳 xff0c 调参的过程无疑是漫长而艰难的 连续调了俩天的参数
  • Lua 字符串

    Lua 字符串 参考至菜鸟教程 字符串或串 String 是由数字 字母 下划线组成的一串字符 Lua 语言中字符串可以使用以下三种方式来表示 xff1a 单引号间的一串字符 双引号间的一串字符 与 间的一串字符 以上三种方式的字符串实例如
  • Lua 迭代器

    Lua 迭代器 参考文章 xff1a 菜鸟教程 https cloud tencent com developer article 2203215 迭代器 xff08 iterator xff09 是一种对象 xff0c 它能够用来遍历标准
  • Lua table(表)

    Lua table 表 参考至菜鸟教程 Lua table 使用关联型数组 xff0c 你可以用任意类型的值来作数组的索引 xff0c 但这个值不能是 nil Lua table 是不固定大小的 xff0c 你可以根据自己需要进行扩容 Lu
  • Lua 模块与包

    Lua 模块与包 参考至菜鸟教程 模块类似于一个封装库 xff0c 从 Lua 5 1 开始 xff0c Lua 加入了标准的模块管理机制 xff0c 可以把一些公用的代码放在一个文件里 xff0c 以 API 接口的形式在其他地方调用 x
  • Lua 文件I/O

    Lua 文件I O 参考至菜鸟教程 Lua I O 库用于读取和处理文件 分为简单模式 xff08 和C一样 xff09 完全模式 简单模式 xff08 simple model xff09 拥有一个当前输入文件和一个当前输出文件 xff0
  • Lua 错误处理

    Lua 错误处理 参考至菜鸟教程 程序运行中错误处理是必要的 xff0c 在我们进行文件操作 xff0c 数据转移及web service 调用过程中都会出现不可预期的错误 如果不注重错误信息的处理 xff0c 就会造成信息泄露 xff0c
  • Lua 调试(Debug)

    Lua 调试 Debug 参考至菜鸟教程 Lua 提供了 debug 库用于提供创建我们自定义调试器的功能 Lua 本身并未有内置的调试器 xff0c 但很多开发者共享了他们的 Lua 调试器代码 Lua 中 debug 库包含以下函数 x
  • Lua 垃圾回收

    Lua 垃圾回收 参考至菜鸟教程 Lua 采用了自动内存管理 这意味着你不用操心新创建的对象需要的内存如何分配出来 xff0c 也不用考虑在对象不再被使用后怎样释放它们所占用的内存 Lua运行了一个垃圾收集器来收集所有死对象 xff08 即
  • Lua 面向对象(详解)

    Lua 面向对象 xff08 详解 xff09 参考文章 xff1a https blog csdn net linxinfa article details 103254828 https zhuanlan zhihu com p 115
  • Lua实现矩阵的加减乘除

    Lua实现矩阵的加减乘除 参考文章 xff1a https blog csdn net qq 54180412 article details 122943327 https www bilibili com video BV1434y18
  • ubuntu系统配置大恒相机驱动并读取ros话题

    文章目录 0 说明1 安装大恒相机sdk1 1 下载1 2 安装sdk 用于配置ip和调试相机参数 1 电脑网卡配置 网卡固定ip 2 查看相机图像以及配置相机参数 2 安装ros驱动包 注 xff1a 大恒相机官方没ros驱动 2 0 正
  • C++类对象与Lua之间的交互

    C 43 43 类对象与Lua之间的交互 C语言与Lua进行交互 xff0c 我们可以相对轻易的做到 xff0c 但在实际应用中我们更加偏向于使用C 43 43 与Lua进行交互 xff0c 面向对象编程 关于C语言与Lua之间的调用交互实
  • C++与Lua交互实例 -- 矩阵的加减乘除(版本一)

    C 43 43 与Lua交互实例 矩阵的加减乘除 xff08 版本一 xff09 关于lua中封装的类模板以及相关知识可参考以下链接 xff1a https ufgnix0802 blog csdn net article details
  • C++与Lua交互实例 -- 矩阵的加减乘除(版本二)

    C 43 43 与Lua交互实例 矩阵的加减乘除 xff08 版本二 xff09 TIPS xff1a 关于使用矩阵的加减乘除测试C 43 43 与Lua的交互以及下面没讲述到的知识点可以阅读第一版 xff1a https blog csd