Lua学习笔记——C语言与Lua的交互

来源:互联网 发布:tomcat修改端口号 编辑:程序博客网 时间:2024/05/29 18:19
Lua与C的交互C代码不可以直接与Lua代码交互,中间是通过Lua引擎实现的(C代码要调用Lua需要链上Lua引擎库 gcc lua.c -llua50)gcc lua.c -llua5.1     //链上Lua50引擎库,之后lua.c就可以  如果提示没有lua50库,就使用 sudo apt-get install liblua5.1-0-dev 安装lua引擎库Lua堆栈一般最多可以容纳20个参数第一部分:Lua调用C函数STEP1 执行lua脚本lua.c内容如下#include<lua5.1/lua.h>#include<lua5.1/laulib.h>#include<lua5.1/lualib.h>int main(){//1.创建lua state(Lua解析器实例,类似于java虚拟机)     //将来与Lua交互必须使用创建的解析器实例,  //每个线程可以创建多个解析器实例lua_State* luaInst = lua_open()//2.初始化Lua解析器实例对象luaL_openlibs(luaInst)//3.执行LualuaL_dofile(luaInst,"1.lua")   //执行当前目录下的lua脚本return 0;}当加入main函数,可以实现与系统自带解析器一样的功能#include<lua5.1/lua.h>#include<lua5.1/laulib.h>#include<lua5.1/lualib.h>int main(int argc,char*argv[]){lua_State* luaInst = lua_open()luaL_openlibs(luaInst)luaL_dofile(luaInst,argv[1])   //执行传入参数指定的Lua脚本    return 0;}利用gcc lua.c -llua5.1  生成a.out./a.out  1.lua     与lua 1.lua执行结果一样---------------------------------------------------------------------------STEP2 lua调用C函数lua.c内容如下#include<lua5.1/lua.h>#include<lua5.1/laulib.h>#include<lua5.1/lualib.h>//1. 定义接口函数,接口函数有固定的格式,int(*func_type)(lua_State*)//2.将接口函数注册到lua解析器中//3.执行lua脚本,在脚本中执行对应的函数void callbylua(){printf("this function is called by lua ");}int c1(lua_State* L){callbylua();return 0;}int main(){lua_State* luaInst = lua_open();luaL_openlibs(luaInst,"c1",c1) ;    //注册C函数到LualuaL_dofile(luaInst,"./1.lua");   //执行传入参数指定的Lua脚本    return 0;}1.lua内容如下print("this is 1.lua")c1()---------------------------------------------------------------------------STEP3 lua调用C函数:带有参数lua.c内容如下#include<lua5.1/lua.h>#include<lua5.1/laulib.h>#include<lua5.1/lualib.h>void cprint(int a,int b,char* c){printf("%d,%d,%s\n",a,b,c);}int c2(lua_State* L)        //需要从lua栈中获取三个参数{int a = lua_tonumber(L,1);     //根据lua解析器栈的索引值来获取参数int b = lua_tonumber(L,2);char* c = lua_tostring(L,3);cprint(a,b,c);return 0;}int main(){lua_State* luaInst = lua_open();luaL_openLibs(luainst);lua_register(luaInst,"cprint",c2);luaL_dofile(luaInst,"./1.lua");}1.lua内容如下print("this is 1.lua")c2(10,20,“helloC”)//lua解析器中有一个栈,栈中的元素从左往右,依次是栈底,到栈顶;索引栈分为索引与 尾索引(负数)---------------------------------------------------------------------------STEP4 lua调用C函数:带有参数和返回值lua.c内容如下#include<lua5.1/lua.h>#include<lua5.1/laulib.h>#include<lua5.1/lualib.h>int cadd(int x,int y){return x+y;}int c4(lua_State* L){int x = lua_tonumber(L,1);int y = lua_tonumber(L,2);int s = cadd(x,y);lua_pushnumber(L,s);       //返回值return 1;                //返回有多少个返回值}int main(){lua_State* luaInst = lua_open();luaL_openLibs(luainst);lua_register(luaInst,"cadd",c4)luaL_dofile(luaInst,"./1.lua")}1.lua内容如下print("this is 1.lua")ret = cadd(10,20)//lua解析器中有一个栈,栈中的元素从左往右,依次是栈底,到栈顶;索引栈分为索引与 尾索引(负数)print("cadd ret =",ret)---------------------------------------------------------------------------STEP5 lua调用C函数:带有参数和返回值lua.c内容如下#include<lua5.1/lua.h>#include<lua5.1/laulib.h>#include<lua5.1/lualib.h>void cswap(int* x,int* y){return x+y;}int c5(lua_State* L){int x = lua_tonumber(L,1);int y = lua_tonumber(L,2);cswap(x,y);lua_pushnumber(L,x);       //返回值lua_pushnumber(L,y);       //返回值return 2;                //返回有多少个返回值}int main(){lua_State* luaInst = lua_open();luaL_openLibs(luainst);lua_register(luaInst,"cswap",c5)luaL_dofile(luaInst,"./1.lua")}1.lua内容如下print("this is 1.lua")a,b = cswap(10,20)//lua解析器中有一个栈,栈中的元素从左往右,依次是栈底,到栈顶;索引栈分为索引与 尾索引(负数)print("cadd ret =",a,b)第二部分:C调用Lua函数#include <lua5.1/lua.h>#include <lua5.1/lauxlib.h>#include <lua5.1/lualib.h>// 1. 调用一个没有参数,没有返回值的函数// call lua function: fooint main1(int argc, char* argv[]){// 创建一个Lua解析器环境实例,类似Java的虚拟机lua_State* luaInst = lua_open();// 初始化Lua解析器环境实例对象luaL_openlibs(luaInst);// 执行LualuaL_dofile(luaInst, "2.lua");// 在调用lua_call函数去调用lua函数之前,需要把lua的函数放入栈(foo是一个Lua中的函数变量)lua_getglobal(luaInst, "foo"); // 调用lua的一个函数,有没有指定哪个函数????   第二个参数是所调用函数的参数个数,第三个参数是返回值的个数lua_call(luaInst, 0, 0);         //没有指定具体的函数,解析器的栈决定     ;该函数调用完毕之后,解析器栈内部会清空return 0;}----2.lua的内容function foo()print("foo in lua is called")end// 2. 调用一个有参数的函数int main2(int argc, char* argv[]){    // 创建一个Lua解析器环境实例,类似Java的虚拟机    lua_State* luaInst = lua_open();    // 初始化Lua解析器环境实例对象    luaL_openlibs(luaInst);    // 执行Lua    luaL_dofile(luaInst, "2.lua");    // 在调用lua_call函数去调用lua函数之前,需要把lua的函数放入栈    lua_getglobal(luaInst, "luaprint"); // foo其实是一个函数类型变量    lua_pushnumber(luaInst, 100);    lua_pushstring(luaInst, "hello");    // 调用lua的foo函数,有没有指定哪个函数????    lua_call(luaInst, 2, 0);     return 0;}----2.lua的内容function luaprint(x, y)print("lua get arg:", x, y)end// 3. 调用一个有返回值的函数int main(int argc, char* argv[]){// 创建一个Lua解析器环境实例,类似Java的虚拟机lua_State* luaInst = lua_open();// 初始化Lua解析器环境实例对象luaL_openlibs(luaInst);// 执行LualuaL_dofile(luaInst, "2.lua");// 在调用lua_call函数去调用lua函数之前,需要把lua的函数放入栈lua_getglobal(luaInst, "luaadd"); // foo其实是一个函数类型变量lua_pushnumber(luaInst, 100);lua_pushnumber(luaInst, 200);// 调用lua的foo函数,有没有指定哪个函数????lua_call(luaInst, 2, 1);int result = lua_tonumber(luaInst, -1);printf("luaadd result is %d\n", result);lua_pop(luaInst, 1); // POP 一个元素,保证栈被清空return 0;}----3.lua的内容function luaadd(x, t)return x+y;end第三部分:Lua与C/C++纯数据交互原理:Lua解析器实际是将Lua脚本中的语句翻译为C代码保存在Lua解析器中,因而可以使用C直接编辑Lua解析器中的数据结构lua.c内容如下://向lua解析器中写入变量a并赋值#include <lua5.1/lua.h>#include <lua5.1/lauxlib.h>#include <lua5.1/lualib.h>// 放一个普通的全局变量int main1(int argc, char* argv[]){// 创建一个Lua解析器环境实例,类似Java的虚拟机lua_State* luaInst = lua_open();// 初始化Lua解析器环境实例对象luaL_openlibs(luaInst);// push一个value到栈lua_pushnumber(luaInst, 100);     //为lua_setglobal做铺垫,因为此时栈为空// 放一个a变量lua_setglobal(luaInst, "a");     //lua_setglobal函数执行过程为:从栈顶获取一个值赋值给“a”,然后将栈顶元素弹出来;将a压入堆栈// 执行LualuaL_dofile(luaInst, "3.lua");return 0;}//3.lua中的内容为print(a)       //虽然3.lua没有a变量,但是C语言已经将a加入了栈中// 放一个表int main2(int argc, char* argv[]){// 创建一个Lua解析器环境实例,类似Java的虚拟机lua_State* luaInst = lua_open();// 初始化Lua解析器环境实例对象luaL_openlibs(luaInst);// 阶段1:先创建全局表b// push一个value到栈lua_newtable(luaInst);// 放一个b变量lua_setglobal(luaInst, "b");// 阶段2:给b来一个成员,叫name                                 lua_getglobal(luaInst, "b"); // 将b表,放入栈                   |__________|lua_pushstring(luaInst, "tom");                                 |__________|目前栈顶是“tom”   -1位置       key是"name"  value是"tom"lua_setfield(luaInst, -2, "name"); // b.name = "tom"            |__________|栈顶下面有一个table -2位置|__________|// 执行LualuaL_dofile(luaInst, "3.lua");return 0;}int main3(){// 创建一个Lua解析器环境实例,类似Java的虚拟机lua_State* luaInst = lua_open();// 初始化Lua解析器环境实例对象luaL_openlibs(luaInst);//这类函数需要考虑栈的具体状态,需要查看各个函数弹栈与否,画图分析lua_newtable(luaInst);lua_pushstring(luaInst, "tom");lua_setfield(luaInst, -2, "name");lua_setglobal(luaInst, "b");//简化/优化上面的代码,setfield会弹出tom的值,但是表还在luaL_dofile(luaInst, "3.lua");}int main(){lua_State* luaInst = lua_open();luaL_openlibs(luaInst);lua_newtable(luaInst);lua_pushnumber(luaInst, 1);lua_pushstring(luaInst, "hello lua");lua_settable(luaInst, 1);//相当于t[k] = v   操作   ,(由于setfield下标是字符串,settable下标是数字)lua_setglobal(luaInst, "b");luaL_dofile(luaInst, "3.lua");}3.lua内容如下:print(a)print(b.name)print(b[1])

0 0
原创粉丝点击