LUA与C API

lua与c之间,通过栈交互,
关系如下图20140907173703062
下载lua库 导入工程,下面是交互的几个例子

extern "C"
{
    #include "lua.h"
    #include "lualib.h"
    #include "lauxlib.h"
}
//C调用lua 例1
void Test1() {
    int len = 0;
    lua_State * L = lua_open();//开启 虚拟机
    luaL_dofile(L, "E:/Works/Lua/重新学习lua/TestLua/Debug/Test.lua");//执行lua脚本 ps: window={width=300,height=100}
    len = lua_gettop(L);//查询当前的堆栈个数
    lua_getglobal(L, "window");//将lua脚本中的参数压入栈中 这里window 是一个表
    lua_pushstring(L, "width");//将width 字符串压入栈中,width 这个其实是lua文件中的window表的一个key值
    lua_gettable(L, -2);//将“width”->替换成value, -2是指window的栈index
    //len = lua_gettop(L);//查询当前的堆栈个数
    int width = lua_tonumber(L, -1);//获得number值,-1就是上面的value值
    lua_pop(L, 1);//出栈,1个参数
    //len = lua_gettop(L);//查询当前的堆栈个数
    lua_pushstring(L, "height");//将“height”压入栈中,height 这个其实是lua文件中的window表的一个key值
    lua_gettable(L, -2);//将“height”->替换成value, -2是指window的栈index
    int height = lua_tonumber(L, -1);//获得number值,-1就是上面的value值
    //len = lua_gettop(L);//查询当前的堆栈个数
    lua_close(L);//关闭 虚拟机
    scanf("%s");
}
//lua 调用c 的参数
void Test2() {
    lua_State *L = lua_open();//开启 lua虚拟机
    luaopen_base(L);//加载基础库 如 print
    lua_pushnumber(L, 250);//向堆栈压入number值=250
    lua_setglobal(L, "number");//将250赋值给number
    luaL_dofile(L, "E:/Works/Lua/重新学习lua/TestLua/Debug/Test.lua");//调用 lua脚本 ps: print(number)
    int n = lua_gettop(L);//查询当前的堆栈个数
    lua_close(L);//关闭 虚拟机
    scanf("%s");
}
//lua 调用c的table参数
void Test3() {

    lua_State *L = lua_open();//开启 虚拟机
    luaopen_base(L);//加载lua基础库 如print
    lua_newtable(L);//创建一个表
    lua_pushstring(L, "number1");//入栈一个string=“number1”
    lua_pushnumber(L, 250);//入栈一个number
    lua_settable(L, -3);//让table的number1->250, -3 是table的栈下标,然后把string,和value 出栈

    lua_pushstring(L, "number2");//入栈一个string=“number2”
    lua_pushnumber(L, 400);//入栈一个number
    lua_settable(L, -3);//让table的number2->400,-3是table的栈下标,然后把string,和value 出栈
    lua_setglobal(L, "_Table");//table 命名为_Table 入栈
    int n = lua_gettop(L);//这里查看栈内个数 ps: n=2;
    luaL_dofile(L, "E:/Works/Lua/重新学习lua/TestLua/Debug/Test.lua");//调用 lua脚本 ps: print(_Table.number1,_Table.number2)
    lua_close(L);//关闭 虚拟机
    scanf("%s");
}
//定义函数
int getWidth(lua_State *L)
{
    int top = lua_gettop(L);//查看当前栈内个数 ps: n=1
    int n = lua_tonumber(L, 1);//读取number 栈index=1
    lua_pushnumber(L, 11111 * n);//压入栈 1111*n
    lua_pushnumber(L, 22222 * n);//压入栈 2222*n
    return 2;//返回值为2
}
//lua 调用c定义的方法
void Test4() {
    
    lua_State *L = lua_open();//开启虚拟机
    luaopen_base(L);//加载lua基础库 如print
    lua_pushcfunction(L, getWidth);//压入函数 getWidth
    lua_setglobal(L, "getWidth");//压入string->getWidth   
    lua_pushnumber(L, 9);//压入number->9
    lua_setglobal(L, "number");//将9赋值给number
    int t = lua_gettop(L);//查看栈内个数 ps: n=3
    luaL_dofile(L, "E:/Works/Lua/重新学习lua/TestLua/Debug/Test.lua");//调用 lua脚本 ps: print(number,getWidth(number))
    scanf("%s");
    lua_close(L);   
}
typedef struct STR_WIN
{
    int width;
    int height;
}STR_WIN;

int getwidth(lua_State * L) {
    STR_WIN * p = (STR_WIN *)luaL_checkudata(L, 1, "win.meta");//检测 1的值是不是win.meta,win.meta是元表
    if (p != NULL)
    {
        lua_pushnumber(L, p->width);//将width压入栈中,给lua调用
        return 1;//返回1
    }
    return 0;//如果错误,返回0
}
int getheight(lua_State *L) {
    STR_WIN * p = (STR_WIN *)luaL_checkudata(L, 1, "win.meta");//检测 1的值是不是win.meta,win.meta是元表
    if (p != NULL)
    {
        lua_pushnumber(L, p->height);//将width压入栈中,给lua调用
        return 1;//返回1
    }
    return 0;//如果错误,返回0
}

//注册方法
static const luaL_reg win[] = {
    { "get_width",getwidth },
    { "get_height",getheight }
};

int newobject(lua_State *L) {
    int width = lua_tonumber(L, -2);//获得栈内-2 number->width
    int height = lua_tonumber(L, -1);//获得栈内-1 number->height
    STR_WIN *p = (STR_WIN *)lua_newuserdata(L, sizeof(STR_WIN));//压入一个userdata
    p->width = width;
    p->height = height;
    int n = lua_gettop(L);//获得当前的栈个数
    luaL_getmetatable(L, "win.meta");//将win.meta 压入栈
    lua_setmetatable(L, -2);//为STR_WIN 设置元表win.meta

    return 1;
}
static const luaL_reg fun[] =
{
    { "new",newobject }
};
//lua调用c 用注册的方法,调用定义的结构体
void Test5() {
    lua_State *L = lua_open();//开启虚拟机
    luaopen_base(L);//加载lua基础库 如print
    luaL_openlib(L, "f", fun, 0);//注册一组函数 ,命名f
    luaL_openlib(L, "_Func", win, 0);//注册一组函数,命名_Func
    luaL_newmetatable(L, "win.meta");//创建一个元表命名 win.meta
    lua_pushstring(L, "__index");//压入 string -> __index
    int n = lua_gettop(L);//栈内个数->6
    lua_pushvalue(L, -3);//将栈中-3对应的值 压入栈
    n = lua_gettop(L);//栈内个数->7
    lua_settable(L, -3);//-3 =win.meta 表  将__index=_Func
    luaL_dofile(L, "E:/Works/Lua/重新学习lua/TestLua/Debug/Test.lua");//调用 lua脚本 ps: local o=f.new(400,300); print(o:get_width(), o : get_height())

    lua_close(L);
    scanf("%s");
}