为什么要C/C++
- 流行的语言,学习人员多
- 高性能,对于嵌入式设备则是省电
- 大量的第三方库
为什么要Lua
- C++缺点:编译慢,调试难,学习难度大
- Lua优点:
- 最快的脚本语言
- 可以编译调试
- 与C/C++结合容易
- Lua是对性能有要求的必备脚本
lua基本语法
lua基础数据类型和变量
- 全局变量
b = 10
- 局部变量:尽量使用局部变量,保证变量控制
local b = 10
数据类型
NIL
- 用于区分具有一些数据或者没有数据的值
- 全局变量设置为nil会交给垃圾回收
local a = nil print(type(a)) --> nil
Booleans
- Lua中所有的值都可以作为条件
- 除了false和nil为假以外,其他的值都为真,0为真
Numbers
- Lua中没有整数,都是用浮点数进行运算
- 对应的c中的double类型
- 新版中有基于64位的整形
- tonumber()转换格式
Strings
- tostring()格式转换
- [[]]多行字符串赋值
- 与C一样转义\
- …字符串拼接
- String 处理
- 字符串长度string.len
- 字符串子串string.sub(str, 3, 5)
- 字符串查找local b,e = string.find(str, “HEAD”) 支持正则
- 字符串替换string.gsub(str, "HEAD, “XCJ”)
lua控制结构语句
条件判断
- if 条件语句
if conditions then
tehn-part
elseif condition then
elseif-part
else
else-part
end
- 逻辑运算
- and or not
- < > <= >= ~= ==
循环语句
- while循环语句
while condition do
statements
end
break 退出循环
- repeat循环语句
repeat
statements
until conditions
break 退出循环
- for 循环语句
/// 1
for var=from, to, step do
loop-part
end
/// 2
for i,v in ipairs(a) do
print(v)
end
break 退出循环
lua表和函数
lua表
- 表的大小 table.getn(t1)
- 插入 table.insert(a, pos, line)
- 不传pos相当于push_back
- 删除table.remove(a, pos)返回这次删除的值
- 不传pos相当于pop_back
local tab1 = {"001", "002", "003"}
for i, v in ipairs(tab1) do
print(i..":"..v)
end
print("======= insert =======")
table.insert(tab1, 3, "002-2")
table.insert(tab1, "004")
for i, v in ipairs(tab1) do
print(i..":"..v)
end
print("======= remove =======")
table.remove(tab1, 3)
table.remove(tab1)
for i, v in ipairs(tab1) do
print(i..":"..v)
end
local tab1 = { id = 123, age = 20}
tab1["name"] = "aaa"
print("====== insert ======")
for k, v in pairs(tab1) do
print(k..":"..v)
end
print("====== remove ======")
tab1["id"] = nil
for k, v in pairs(tab1) do
print(k..":"..v)
end
print("====== tab3 ======")
local tab3 = {}
tab3[1] = {"1", "2"}
tab3[2] = {"3", "4"}
for k, v in pairs(tab3) do
for k2, v2 in pairs(v) do
print(k.."::"..k2..":"..v2)
end
end
lua函数
- 函数语法
function func_name(args)
statement-list;
end
function test1(args)
print(args)
end
function test2(args)
return 1
end
test1(11)
print(test2(11))
lua调用C++
函数调用
#include <iostream>
extern "C"
{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
int test(lua_State* L)
{
printf("int test");
return 0;
}
int main()
{
lua_State *L = lua_open();
luaopen_base(L);
luaopen_string(L);
luaopen_table(L);
lua_register(L, "test", test);
luaL_loadfile(L, "main.lua");
lua_pcall(L, 0, 0, 0);
return 0;
}
test()
参数传递
- 传递普通参数
#include <iostream>
extern "C"
{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
int test(lua_State* L)
{
printf("int test\n");
size_t len;
const char* str = lua_tolstring(L, 1, &len);
printf("lua args %s\n", str);
int age = lua_tointeger(L, 2);
printf("lua args %d\n", age);
return 0;
}
int main()
{
lua_State *L = lua_open();
luaopen_base(L);
luaopen_string(L);
luaopen_table(L);
lua_register(L, "test", test);
luaL_loadfile(L, "main.lua");
lua_pcall(L, 0, 0, 0);
return 0;
}
test("hello lua", 123)
- 传递数组
#include <iostream>
extern "C"
{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
int test(lua_State* L)
{
printf("int test\n");
size_t len;
const char* str = lua_tolstring(L, 1, &len);
printf("lua args %s\n", str);
int age = lua_tointeger(L, 2);
printf("lua args %d\n", age);
return 0;
}
int test_array(lua_State *L)
{
printf("init test_array\n");
int len = luaL_getn(L, 1);
for (int i = 0; i < len; i++)
{
lua_pushnumber(L, i + 1);
lua_gettable(L, 1); // pop idx push 压入table
size_t len;
printf("%s\n", lua_tolstring(L, -1, &len));
lua_pop(L, 1);
}
return 0;
}
int main()
{
lua_State *L = lua_open();
luaopen_base(L);
luaopen_string(L);
luaopen_table(L);
lua_register(L, "test", test);
lua_register(L, "test_array", test_array);
luaL_loadfile(L, "main.lua");
lua_pcall(L, 0, 0, 0);
return 0;
}
local tab = {"001", "002", "003"}
test_array(tab)
- 传递kv表
int test_array2(lua_State *L)
{
printf("init test_array2\n");
// lua_pushnil(L);
// while (lua_next(L, 1) != 0)
// {
// printf("key = %s\n", lua_tostring(L, -2));
// printf("value = %s\n", lua_tostring(L, -1));
// lua_pop(L, 1);
// }
lua_getfield(L, 1, "age");
printf("age = %s\n", lua_tostring(L, -1));
return 0;
}
local tab = {name="xiaoming", age="22", id="007"}
test_array2(tab)
- C++参数类型检查
int test_array2(lua_State *L)
{
luaL_checktype(L, 1, LUA_TTABLE);
if (lua_type(L, 2) != LUA_TNUMBER)
{
printf("arg2 is not number\n");
}
printf("init test_array2\n");
lua_getfield(L, 1, "age");
printf("age = %s\n", lua_tostring(L, -1));
return 0;
}
local tab = {name="xiaoming", age="22", id="007"}
local size = "108"
test_array2(tab, size)
返回值获取
- C++返回值普通类型
int test_ret(lua_State *L)
{
lua_pushstring(L, "test_ret");
return 1;
}
print(test_ret())
- 返回对象
int test_ret(lua_State *L)
{
lua_newtable(L);
lua_pushstring(L, "name");
lua_pushstring(L, "zhangsan");
lua_settable(L, -3);
lua_pushstring(L, "age");
lua_pushnumber(L, 21);
lua_settable(L, -3);
return 1;
}
tab = test_ret()
print(tab["name"])
print(tab["age"])
C++调用lua
全局变量访问(普通、表)
int main()
{
lua_State *L = lua_open();
luaopen_base(L);
luaopen_string(L);
luaopen_table(L);
lua_register(L, "test", test);
lua_register(L, "test_array", test_array);
lua_register(L, "test_array2", test_array2);
lua_register(L, "test_ret", test_ret);
lua_pushstring(L, "hello");
lua_setglobal(L, "test1_hello");
lua_newtable(L);
lua_pushstring(L, "name");
lua_pushstring(L, "lisi");
lua_settable(L, -3);
lua_setglobal(L, "test1_table");
if (luaL_loadfile(L, "main.lua"))
{
const char *error = lua_tostring(L, -1);
printf("lua call error: %s\n", error);
return -1;
}
if (lua_pcall(L, 0, 0, 0))
{
const char *error = lua_tostring(L, -1);
printf("lua call error: %s\n", error);
return -1;
}
lua_getglobal(L, "width");
int width = lua_tonumber(L, -1);
lua_pop(L, 1);
printf("width = %d\n", width);
lua_getglobal(L, "tab1");
lua_getfield(L, -1, "name");
printf("%s\n", lua_tostring(L, -1));
lua_getfield(L, -2, "age");
printf("%d\n", (int)lua_tonumber(L, -1));
lua_pop(L, 3);
lua_close(L);
return 0;
}
width = 20
tab1 = {name="zhangsan", age=20}
print(test1_hello)
for i, v in pairs(test1_table) do
print(i..":"..v)
end
函数调用(参数,返回值)
int main()
{
lua_State *L = lua_open();
luaopen_base(L);
luaopen_string(L);
luaopen_table(L);
lua_register(L, "test", test);
lua_register(L, "test_array", test_array);
lua_register(L, "test_array2", test_array2);
lua_register(L, "test_ret", test_ret);
lua_pushstring(L, "hello");
lua_setglobal(L, "test1_hello");
lua_newtable(L);
lua_pushstring(L, "name");
lua_pushstring(L, "lisi");
lua_settable(L, -3);
lua_setglobal(L, "test1_table");
if (luaL_loadfile(L, "main.lua"))
{
const char *error = lua_tostring(L, -1);
printf("lua call error: %s\n", error);
lua_pop(L, 1);
}
if (lua_pcall(L, 0, 0, 0))
{
const char *error = lua_tostring(L, -1);
printf("lua call error: %s\n", error);
lua_pop(L, 1);
}
lua_getglobal(L, "width");
int width = lua_tonumber(L, -1);
lua_pop(L, 1);
printf("width = %d\n", width);
lua_getglobal(L, "tab1");
lua_getfield(L, -1, "name");
printf("%s\n", lua_tostring(L, -1));
lua_getfield(L, -2, "age");
printf("%d\n", (int)lua_tonumber(L, -1));
lua_pop(L, 3);
// 调用函数
lua_getglobal(L, "event");
lua_pushstring(L, "key");
lua_pushstring(L, "value");
if (lua_pcall(L, 2, 1, 0) != 0)
{
const char *error = lua_tostring(L, -1);
printf("lua call error: %s\n", error);
lua_pop(L, 1);
}
else
{
printf("lua call error: %s\n", lua_tostring(L, -1));
lua_pop(L, 1);
}
printf("top is %d\n", lua_gettop(L));
lua_close(L);
return 0;
}
width = 20
tab1 = {name="zhangsan", age=20}
print(test1_hello)
for i, v in pairs(test1_table) do
print(i..":"..v)
end
function event(key, value)
print("key:"..key.." value:"..value)
return "aaaaa"
end
function event(args)
for i,v in ipairs(args) do
print("key:"..i.." value:"..v)
end
end
备注: 注意栈空间清理,防止内存泄露, 防止多线程互斥问题。