• lua移植及使用


    编译环境:Ubuntu16.04 64位
    交叉编译工具:arm-hisiv500-linux-gcc

    1. 项目背景

    使用lua脚本,读取key对应的值,用作设备的默认配置。

    2. lua开源版本选择

    使用lua-5.4.6.tar.gz点击下载,早期使用lua-5.0.2.tar.gz,在部分平台上存在浮点运算错误的问题,放弃。

    3. 封装代码

    3.1 源码简介

    源码的目录结构比较简单,只有一个src目录,Makefile略作修改即可,或者根据自己项目做简化。
    lua.hpp文件内容如下,外部调用主要用到就是这三个头文件,在编译C++工程时注意extern “C”:

    // lua.hpp
    // Lua header files for C++
    // <> not supplied automatically because Lua also compiles as C++
    
    extern "C" {
    #include "lua.h"
    #include "lualib.h"
    #include "lauxlib.h"
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.2 封装类

    3.2.1 头文件

    #ifndef __LUA_CONFIG_H__
    #define __LUA_CONFIG_H__
    
    #include 
    #include 
    
    struct lua_State;
    typedef struct lua_State lua_State;
    
    class LuaConfig
    {
    public:
        static int Initialize(void);
        static int Invalidate(void);
        static LuaConfig* instance(void);
    private:
        static LuaConfig* s_instance;
    
        LuaConfig(void);
        virtual ~LuaConfig(void);
        LuaConfig(LuaConfig &);			// 拷贝构造函数,禁止拷贝
    
    public:
        int Init(const char * filename);//要解析的lua文件,可以按照lua语法包含其他lua
        void unInit();
    
    	///< 根据传入的键值返回相应的字符串
        ///< key为要访问的键值
        ///< defaultValue为默认值,当访问的键值不存在时返回
        std::string getString(const char * key, const char * defaultValue="");
    
        ///< 根据传入的键值返回相应的double值,与getString类似
        ///< key为要访问的键值
        ///< defaultValue为默认值,当访问的键值不存在时返回
        double getNumber(const char * key, double defaultValue = 0);
    
    private:
        int TravelTable(const char * key);
    
    private:
        lua_State *m_luastate;
    	pthread_mutex_t m_Mutex;
    };
    
    #endif //__LUA_CONFIG_H__
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    3.2.2 类的实现

    #include "LuaConfig.h"
    #include 
    #include 
    
    extern "C"
    {
    	#include "lua/lua.h"
    	#include "lua/lauxlib.h"
    	#include "lua/lualib.h"
    };
    
    
    int LuaConfig::Initialize(void)
    {
    	if(s_instance != NULL)
    		return -1;
    
    	s_instance = new LuaConfig;
    	return 0;
    }
    int LuaConfig::Invalidate(void)
    {
    	if(s_instance == NULL)
    		return 0;
    
    	delete s_instance;
    	return 0;
    }
    LuaConfig* LuaConfig::instance(void)
    {
    	return s_instance;
    }
    
    LuaConfig* LuaConfig::s_instance = NULL;
    
    LuaConfig::LuaConfig()
    {
        m_luastate = NULL;
        pthread_mutex_init(&m_Mutex, NULL);
    }
    
    LuaConfig::~LuaConfig()
    {
        unInit();
        pthread_mutex_destroy(&m_Mutex);
    }
    
    int LuaConfig::Init(const char * filename)
    {
        if (m_luastate != NULL)
            return -1;
    
        if (filename == NULL)
            return -2;
    #if 0 // 5.0.2的封装
    	m_luastate = lua_open();
        if (m_luastate == NULL)
            return -3;
    
        luaopen_base(m_luastate);
        luaopen_table(m_luastate);
        luaopen_io(m_luastate);
        luaopen_string(m_luastate);
        luaopen_math(m_luastate);
        luaopen_debug(m_luastate);
        //luaopen_lfs(m_luastate);
        //luaopen_bitlib(m_luastate);
    
        if (lua_dofile(m_luastate, filename) != 0)
            return -4;
    #else//5.4.6
        m_luastate = luaL_newstate();
        if (m_luastate == NULL)
            return -3;
    
    	luaL_openlibs(m_luastate);
        if (luaL_dofile(m_luastate, filename) != 0)
            return -4;
    #endif
        return 0;
    }
    
    void LuaConfig::unInit()
    {
        if (m_luastate != NULL)
        {
            lua_close(m_luastate);
            m_luastate = NULL;
        }
    	return;
    }
    
    std::string LuaConfig::getString(const char * key, const char * defaultValue)
    {
    	pthread_mutex_lock(&m_Mutex);
    
    	int nTop   = lua_gettop(m_luastate);
    	int status = TravelTable(key);
    	std::string ret = defaultValue;
    
    	if( (status == 0) && (lua_isstring(m_luastate, -1)))
    	{
    		ret = lua_tostring(m_luastate, -1);
    	}
    
    	lua_settop(m_luastate, nTop);
    	pthread_mutex_unlock(&m_Mutex);
    	return ret;
    }
    
    double LuaConfig::getNumber(const char * key, double defaultValue)
    {
    	pthread_mutex_lock(&m_Mutex);
    	int nTop   = lua_gettop(m_luastate);
    	int status = TravelTable(key);
    	double ret = defaultValue;
    
    	if( (status == 0) && (lua_isnumber(m_luastate, -1)))
    	{
    		ret = lua_tonumber(m_luastate, -1);
    	}
    
    	lua_settop(m_luastate, nTop);
    	pthread_mutex_unlock(&m_Mutex);
    	return ret;
    }
    
    int LuaConfig::TravelTable(const char * key)
    {
        // 创建匿名函数
    	int len = strlen(key) + 16;
    	char* szFunc = (char*)malloc(len);
    	memset(szFunc, 0, len);
    	sprintf(szFunc, "return %s", key);
    
    	int status = luaL_loadbuffer(m_luastate, szFunc, strlen(szFunc), "table_travel");
    	if(status == 0)
    	{
    		status = lua_pcall(m_luastate, 0, LUA_MULTRET, 0);
    	}
    	free(szFunc);
    	return status;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144

    3.3.3 sample代码

    LuaConfig::Initialize();
    LuaConfig* pCfg = LuaConfig::instance();
    pCfg->Init("./test.lua");
    
    int testA = (int)LuaConfig::instance()->getNumber("testA", 0);
    std::string testB = LuaConfig::instance()->getString("testB", "123456");
    
    if (pCfg != NULL)
    {
    	pCfg->unInit();
    	LuaConfig::Invalidate();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    以上。
    转载请注明出处,如有错漏之处,敬请指正。

  • 相关阅读:
    CSS 自动宽度设置
    按图搜索淘宝商品(拍立淘)API接口 搜爆款商品 图片搜索功能api 调用示例
    28-搭建Keepalived+LVS+Nginx高可用集群负载均衡
    python--numpy常用属性及方法
    SAP PO精炼图
    Springboot整合Mybatis
    只会postman单接口测试?这些高级功能你必须掌握
    低度酒赛道进入洗牌期,新品牌如何破局三大难题?
    dif请求与响应
    Java(SpringBoot05)
  • 原文地址:https://blog.csdn.net/weixin_43549602/article/details/134089374