Lua简介 Lua 是一门扩展式程序设计语言,被设计成支持通用过程式编程,并有相关数据描述设施。 同时对面向对象编程、函数式编程和数据驱动式编程也提供了良好的支持。 它作为一个强大、轻量的嵌入式脚本语言,可供任何需要的程序使用。 Lua 由 clean C(标准 C 和 C++ 间共通的子集) 实现成一个库。
作为一门扩展式语言,Lua 没有 “main” 程序的概念: 它只能 嵌入 一个宿主程序中工作, 该宿主程序被称为 被嵌入程序 或者简称 宿主 。 宿主程序可以调用函数执行一小段 Lua 代码,可以读写 Lua 变量,可以注册 C 函数让 Lua 代码调用。 依靠 C 函数,Lua 可以共享相同的语法框架来定制编程语言,从而适用不同的领域。 Lua 的官方发布版包含一个叫做 lua
的宿主程序示例, 它是一个利用 Lua 库实现的完整独立的 Lua 解释器,可用于交互式应用或批处理。
Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Lua 特性
轻量级 : 它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。
可扩展 : Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。
其它特性:
支持面向过程(procedure-oriented)编程和函数式编程(functional programming);
自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象;
语言内置模式匹配;闭包(closure);函数也可以看做一个值;提供多线程(协同进程,并非操作系统所支持的线程)支持;
通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等。
Lua安装
如果没有时间或意愿自己编译Lua,可单击如下图位置下载生成的二进制文件进行操作,解压即可完成安装。
本文档进行源码编译演示。
VS编译lua源码 lua静态库编译
新建vs静态库工程,将下载的Lua源码引入项目中(除lua.c和luac.c)
将项目改为C编译,不使用预编译头
编译生成静态库。
lua动态库编译 将配置类型更改为动态库
编译生成动态库。
lua解释器编译 将配置类型更改为应用程序
将lua.c引入源文件中;
编译生成lua解释器。
lua编译器编译 将lua.c从源文件中移除,把luac.c引入源文件,目标文件名改为$(ProjectName)c
编译生成lua编译器器。
生成路径下有这些文件
在该路径下运行cmd输入lua5.4.4.exe -i显示如下即为成功,如果需要,可将其配至环境变量下。
Lua项目源码 百度网盘 下载 提取码:oq8j
Lua入门 Lua参考手册 目前5.4只有官网提供的英文手册
中文手册可以参考云风译版 5.3版本
数据类型 Lua 是动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。
Lua 中有 8 个基本类型分别为:nil、boolean、number、string、userdata、function、thread 和 table。
数据类型
描述
nil
这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)。
boolean
包含两个值:false和true。
number
表示双精度类型的实浮点数
string
字符串由一对双引号或单引号来表示
function
由 C 或 Lua 编写的函数
userdata
表示任意存储在变量中的C数据结构
thread
表示执行的独立线路,用于执行协同程序
table
Lua 中的表(table)其实是一个”关联数组”(associative arrays),数组的索引可以是数字、字符串或表类型。在 Lua 里,table 的创建是通过”构造表达式”来完成,最简单构造表达式是{},用来创建一个空表。
基本语法 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 print ("hello lua" )do local num = 100 print (num) end function sayHello () print ("hello" ) end sayHello() function max (a,b) if a>b then return a else return b end end print (max (3 ,5 ))for var = 1 , 100 do print (var) end
表 1 2 3 4 5 6 7 8 9 10 11 12 13 tab = {} tab.word = 'hello' tab.num = 100 tab['name' ] = 'zhangsan' print (tab.name)print (tab['word' ])for k,v in pairs (tab) do print (k,v) end
数组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 arr = {1 ,2 ,3 ,4 ,"hello" } for key, var in pairs (arr) do print (key,var) end arr = {} for var = 1 , 100 do table .insert (arr, 1 , var) end for key,var in pairs (arr) do print (key,var) end
面向对象 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 function People (name) local self = {} local function init () self.name = name end self.sayhello = function () print ("hello " ..self.name) end init() return self end local p = People('zhangsan' )p.sayhello() function Man (name) local self = People(name) self.sayhello = function () print ("the man say hello to " ..self.name) end self.sayhi = function () print ("the man say hello to " ..self.name) end return self end local p = Man('lisi' )p.sayhello()
C++ 调用 Lua C++ 可以获取Lua中的值,可以调用Lua函数,还可以修改Lua文件
1)C++获取Lua值 使用lua_getglobal来获取值,然后将其压栈 使用lua_toXXX将栈中元素取出转成相应的C++类型的值 如果Lua值为table类型的话,通过lua_getfield和lua_setfield获取和修改表中元素的值
2)C++调用Lua函数 使用lua_getglobal来获取函数,然后将其压入栈; 如果这个函数有参数的话,就需要依次将函数的参数也压入栈; 这些准备工作都准备就绪以后,就调用lua_pcall开始调用函数了,调用完成以后,会将返回值压入栈中;
hello.lua
1 2 3 4 5 str = "I am so cool" tbl = {name = "shun" , id = 20114442 } function add (a,b) return a * b end
示例代码
引入头文件
1 2 3 4 5 6 extern "C" { #include "Lua5.4.4/include/lua.h" #include "Lua5.4.4/include/lauxlib.h" #include "Lua5.4.4/include/lualib.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 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 lua_State *L = luaL_newstate(); if (L == NULL ) { return 0 ; } int bRet = luaL_loadfile(L, "hello.lua" ); if (bRet) { cout << "load file error" << endl ; return 0 ; } bRet = lua_pcall(L, 0 , 0 , 0 ); if (bRet) { cout << "pcall error" << endl ; return 0 ; } lua_getglobal(L, "str" ); string str = lua_tostring(L, -1 ); cout << "str = " << str.c_str() << endl ; string str1 = lua_tostring(L, -1 ); cout << "str = " << str1.c_str() << endl ; lua_getglobal(L, "tbl" ); lua_getfield(L, -1 , "name" ); str = lua_tostring(L, -1 ); lua_getfield(L, -2 , "id" ); int id = lua_tonumber(L, -1 ); cout << "tbl:name = " << str.c_str() << endl ; cout << "tbl:id = " << id << endl ; lua_getglobal(L, "add" ); lua_pushnumber(L, 10 ); lua_pushnumber(L, 20 ); int iRet = lua_pcall(L, 2 , 1 , 0 ); if (iRet) { const char *pErrorMsg = lua_tostring(L, -1 ); cout << pErrorMsg << endl ; lua_close(L); return 0 ; } if (lua_isnumber(L, -1 )) { int fValue = lua_tonumber(L, -1 ); cout << "Result is " << fValue << endl ; } lua_pushstring(L, "Master" ); lua_setfield(L, 2 , "name" ); lua_getfield(L, 2 , "name" ); str = lua_tostring(L, -1 ); cout << "tbl:name = " << str.c_str() << endl ; lua_newtable(L); lua_pushstring(L, "A New friend1" ); str = lua_tostring(L, -1 ); lua_setfield(L, -2 , "name" ); lua_getfield(L, -1 , "name" ); str = lua_tostring(L, -1 ); cout << "newtbl:name = " << str.c_str() << endl ; lua_close(L); return 0 ;
源码下载 百度网盘
提取码:lgqi