|
Andy Niu Help
1.0.0.0
|
Lua
变量 | |
| CPP调用lua | |
| lua调用CPP | |
| lua协程 | |
详细描述
变量说明
| CPP调用lua |
1、hello.lua,如下:
niuzibin@ubuntu:~/work/test1$ vi hello.lua
str = "I am so cool"
tbl = {name = "shun", id = 20114442}
function add(a,b)
return a + b
end
2、test.cpp,如下:
niuzibin@ubuntu:~/work/test1$ vi test.cpp
#include <iostream>
#include <string.h>
using namespace std;
extern "C"
{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
int main()
{
//1.创建Lua状态
lua_State *L = luaL_newstate();
if (L == NULL)
{
return 0 ;
}
//2.加载Lua文件
int bRet = luaL_loadfile(L,"hello.lua");
if(bRet)
{
cout<<"load file error"<<endl;
return 0 ;
}
//3.运行Lua文件
bRet = lua_pcall(L,0,0,0);
if(bRet)
{
cout<<"pcall error"<<endl;
return 0 ;
}
//4.读取变量
lua_getglobal(L,"str");
string str = lua_tostring(L,-1);
cout<<"str = "<<str.c_str()<<endl; //str = I am so cool~
//5.读取table
lua_getglobal(L,"tbl");
lua_getfield(L,-1,"name");
str = lua_tostring(L,-1);
cout<<"tbl:name = "<<str.c_str()<<endl; //tbl:name = shun
//6.读取函数
lua_getglobal(L, "add"); // 获取函数,压入栈中
lua_pushnumber(L, 10); // 压入第一个参数
lua_pushnumber(L, 20); // 压入第二个参数
int iRet= lua_pcall(L, 2, 1, 0);// 调用函数,调用完成以后,会将返回值压入栈中,2表示参数个数,1表示返回结果个数。
if (iRet) // 调用出错
{
const char *pErrorMsg = lua_tostring(L, -1);
cout << pErrorMsg << endl;
lua_close(L);
return 0 ;
}
if (lua_isnumber(L, -1)) //取值输出
{
double fValue = lua_tonumber(L, -1);
cout << "Result is " << fValue << endl;
}
//至此,栈中的情况是:
//=================== 栈顶 ===================
// 索引 类型 值
// 4 int: 30
// 3 string: shun
// 2 table: tbl
// 1 string: I am so cool~
//=================== 栈底 ===================
//7.关闭state
lua_close(L);
return 0 ;
}
3、构建,运行:
niuzibin@ubuntu:~/work/test1$ g++ -o test test.cpp -I/usr/include/lua5.1 /usr/lib/x86_64-linux-gnu/liblua5.1.a
niuzibin@ubuntu:~/work/test1$ ./test
str = I am so cool
tbl:name = shun
Result is 30
| lua协程 |
1、解决什么问题?
考虑下面的应用场景,在车间加工一个产品,分为多个步骤,每个步骤需要从外面拿原料进行处理,每次进来接着上一次的步骤继续向下做。
2、示例代码
niuzibin@ubuntu:~/work/lua$ vi coroutine.lua
function foo (a)
print("foo", a)
return coroutine.yield(2*a)
end
co = coroutine.create(function (a,b)
print("co-body1", a, b)
local r = foo(a+1)
print("co-body2", r)
local r, s = coroutine.yield(a+b, a-b)
print("co-body3", r, s)
return b, "end"
end)
print("1----")
print("main", coroutine.resume(co, 1, 10))
print("2----")
print("main", coroutine.resume(co, "r"))
print("3----")
print("main", coroutine.resume(co, "x", "y"))
print("4----")
print("main", coroutine.resume(co, "x", "y"))
3、运行
niuzibin@ubuntu:~/work/lua$ lua coroutine.lua
1----
co-body1 1 10
foo 2
main true 4
2----
co-body2 r
main true 11 -9
3----
co-body3 x y
main true 10 end
4----
main false cannot resume dead coroutine
4、代码分析
resume 多次进来,每次进来,拿着数据,在现场继续处理。
yield 返回当前步骤的处理结果。
| lua调用CPP |
1、h文件
hello world!niuzibin@ubuntu:~/work/test2$ vi aaa.h
#pragma once
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
extern "C" LUA_API int luaopen_aaa(lua_State *L);//定义导出函数
2、cpp文件
niuzibin@ubuntu:~/work/test2$ vi aaa.cpp
#include <stdio.h>
#include "aaa.h"
static int averageFunc(lua_State *L)
{
int n = lua_gettop(L);
double sum = 0;
int i;
/* 循环求参数之和 */
for (i = 1; i <= n; i++)
sum += lua_tonumber(L, i);
lua_pushnumber(L, sum / n); //压入平均值
lua_pushnumber(L, sum); //压入和
return 2; //返回两个结果
}
static int sayHelloFunc(lua_State* L)
{
printf("hello world!");
return 0;
}
static const struct luaL_Reg myLib[] =
{
{"average", averageFunc},
{"sayHello", sayHelloFunc},
{NULL, NULL} //数组中最后一对必须是{NULL, NULL},用来表示结束
};
int luaopen_aaa(lua_State *L)
{
luaL_register(L, "ss", myLib);
return 1; // 把myLib表压入了栈中,所以就需要返回1
}
3、lua文件
niuzibin@ubuntu:~/work/test2$ vi test.lua
require "aaa"
local ave,sum = ss.average(1,2,3,4,5) -- 参数对应堆栈中的数据
print(ave,sum) -- 3 15
ss.sayHello() -- hello world!
4、构建,运行
niuzibin@ubuntu:~/work/test2$ g++ -fPIC -shared -o aaa.so aaa.cpp -I/usr/include/lua5.1
niuzibin@ubuntu:~/work/test2$ lua test.lua
3 15
特别注意:这里的动态库名称,不带lib,因为要和luaopen_aaa对应。
Copyright (c) 2015~2016, Andy Niu @All rights reserved. By Andy Niu Edit.