c/c++调用Lua,接口简单封装

1 篇文章 0 订阅

封装源码

extern "C"
{
#include "src/lua/include/lua.h"
#include "src/lua/include/lauxlib.h"
#include "src/lua/include/lualib.h"
}

#include <iostream>
#include <cstring>
#include <string>
#include <stdarg.h>
#include <unordered_map>
#include <vector>

#include "src/liblog/liblog.h"

using namespace std;

class NLua
{
public:
    NLua()
    {
    }
    ~NLua()
    {
        if (m_state)
        {
            lua_close(m_state);
            m_state = nullptr;
        }
    }

    void NLua_info()
    {
        nLua_info(m_state);
    }

    bool NLua_init(const char *filename)
    {
        m_state = luaL_newstate();
        if (!m_state)
        {
            if (lua_isstring(m_state, -1))
            {
                logw("Lua状态机初始化失败:[%s]\n", lua_tostring(m_state, -1));
                lua_pop(m_state, 1);
            }
            return false;
        }
        luaL_openlibs(m_state);
        int ret = luaL_dofile(m_state, filename);
        if (0 != ret)
        {
            if (lua_isstring(m_state, -1))
            {
                logw("Lua库打开失败:[%s]\n", lua_tostring(m_state, -1));
                lua_pop(m_state, 1);
            }
            return false;
        }
        return true;
    }

    bool NLua_function(const char *funcname)
    {
        m_param_number = 0;
        int ret = lua_getglobal(m_state, funcname);
        if (0 == lua_isfunction(m_state, -1))
        {
            logw("Lua函数获取失败:[%s]\n", lua_tostring(m_state, -1));
            lua_pop(m_state, 1);
            return false;
        }
        return true;
    }

    template <typename k, typename v>
    bool NLua_setMap(const char *format, const std::unordered_map<k, v> &map)
    {
        lua_newtable(m_state);
        for (std::pair<k, v> it : map)
        {
            loge("%d:%d\n", it.first, it.second);
            switch (format[0])
            {
            case 'i':
                lua_pushinteger(m_state, it.first);
                break;
            default:
                break;
            }
            switch (format[1])
            {
            case 'i':
                lua_pushinteger(m_state, it.second);
                break;

            default:
                break;
            }
            // nLua_info(m_state);
            lua_settable(m_state, -3);
        }
        m_param_number++;
    }

    template <typename T>
    bool NLua_setList(const char *format, const std::vector<T> &list)
    {
        lua_newtable(m_state);

        for (int i = 0; i < list.size(); ++i)
        {
            lua_pushinteger(m_state, i + 1);
            switch (*format)
            {
            case 'i':
                lua_pushinteger(m_state, list.at(i));
                break;
            case 'f':
                lua_pushnumber(m_state, list.at(i));
                break;
            case 's':
                // lua_pushstring(m_state, list.at(i));
                break;
            default:
                break;
            }
            lua_settable(m_state, -3);
        }
        m_param_number++;
    }

    void NLua_setInt(int value)
    {
        lua_pushinteger(m_state, value);
        m_param_number++;
    }

    void NLua_setDouble(double value)
    {
        lua_pushnumber(m_state, value);
        m_param_number++;
    }

    void NLua_setString(const std::string &value)
    {
        lua_pushstring(m_state, value.c_str());
        m_param_number++;
    }

    std::string Nlua_call(const char *format)
    {
        if (LUA_OK != lua_pcall(m_state, m_param_number, 1, 0))
        {
            logw("Lua函数调用失败:[%s]\n", lua_tostring(m_state, -1));
            lua_pop(m_state, 1);
            return NULL;
        }
        std::string value;
        //判断栈顶元素
        switch (*format)
        {
        case 'i':
            if (!lua_isinteger(m_state, -1))
            {
                logw("结果类型不匹配,目标int,结果类型[%s]\n", lua_typename(m_state, lua_type(m_state, -1)));
                lua_pop(m_state, 1);
                return NULL;
            }
            value = std::to_string(lua_tointeger(m_state, -1));
            lua_pop(m_state, 1);
            break;
        case 'f':
            if (!lua_isnumber(m_state, -1))
            {
                logw("结果类型不匹配,目标double,结果类型[%s]\n", lua_typename(m_state, lua_type(m_state, -1)));
                lua_pop(m_state, 1);
                return NULL;
            }
            value = std::to_string(lua_tonumber(m_state, -1));
            lua_pop(m_state, 1);
            break;
        case 's':
            if (!lua_isstring(m_state, -1))
            {
                logw("结果类型不匹配,目标string,结果类型[%s]\n", lua_typename(m_state, lua_type(m_state, -1)));
                lua_pop(m_state, 1);
                return NULL;
            }
            value = lua_tostring(m_state, -1);
            lua_pop(m_state, 1);
            break;
        default:
            break;
        }
        return value;
    }

private:
    void nLua_info(lua_State *L)
    {
        logi("栈中元素个数:%d\n", lua_gettop(L));
        for (int i = 1; i <= lua_gettop(L); ++i)
        {
            logi("栈中元素类型:[%d]-[%s]", i, lua_typename(L, lua_type(L, i)));
            switch (lua_type(L, i))
            {
            case LUA_TNUMBER:
            {
                if (lua_isnumber(L, i))
                {
                    printf("-[%g]", lua_tonumber(L, i));
                }
                else
                {
                    printf("-[%lld]", lua_tointeger(L, i));
                }
            }
            break;
            case LUA_TBOOLEAN:
            {
                printf("-[%s]", lua_toboolean(L, i) ? "true" : "false");
            }
            break;
            case LUA_TSTRING:
            {
                printf("-[%s]", lua_tostring(L, i));
            }
            break;
            case LUA_TNIL:

                break;

            default:
                break;
            }
            printf("\n");
        }
    };

private:
    lua_State *m_state;
    int m_param_number;
};

使用样例
main.cpp

#include <iostream>
#include "NLua.hpp"

int main(int argc, char const *argv[])
{
    NLua lua;
    if (!lua.NLua_init("../main.lua"))
    {
        loge("失败\n");
        return 0;
    }
    if (!lua.NLua_function("hex_bit_1"))
    {
        logi("NLua_function\n");
        return 0;
    }

    std::vector<int> list;
    list.emplace_back(1);
    lua.NLua_setList("i", list);
    lua.NLua_setInt(0);
    lua.NLua_setInt(0);
    lua.NLua_info();

    std::string value = lua.Nlua_call("s");
    if (value.empty())
    {
        logi("Nlua_call\n");
        return 0;
    }
    logi("value = %s\n", value.c_str());
    return 0;
}

main.lua(按比特位校验)

function hex_bit_1(hex, coefficient, bitp)
    local value = 0
    if (#hex ~= 1) then
        return nil
    end
    value = hex[1] & (1 << bitp)
    if (0 == value) then
        return "0"
    end
    return "1"
end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值