c++与Lua的交互

11 篇文章 0 订阅

Lua5.1参考手册


#include <iostream>


#include <stdio.h>

#include "textA.hpp"


using namespace std;

extern "C"

{

#include "lua.h"

#include "lualib.h"

#include "lauxlib.h"

}


/*

 lua.h定义了lua提供的基础函数,提供最基本的功能,在lua.h中的函数都以lua_为前缀(如 lua_open  lua_pcall等)

 lualib.h定义了lua标准库的加载函数,一个新的环境默认是没有载入标准库的,如stringtableiomath等库,除了用于加载指定库的luaopen_开头的函数外,lualib.h还提供了一个luaL_openlibs的方法用于一次性加载所有的标准库。

 lauxlib.h定义了辅助库提供的函数,它们都以luaL_为前缀,这些方法是基于lua.h中提供的方法来造作lua的,laulib.h提供了更加友好、方便的函数让程序员操作lua

 */

//遍历栈中数据

void stackDump(lua_State *L)

{

    int i;

    int top = lua_gettop(L);

    for (i = 1; i <= top; i++)

    {  //遍历所有层

        //lua_type()转换类型

        int t = lua_type(L, i);

        printf("%d",t);

        switch (t)

        {

            case LUA_TSTRING: //字符串

                //获取栈中的变量,然后转换为某个指定的类型,并返回。

                printf("'%s'",lua_tostring(L, i));

                break;

            case LUA_TBOOLEAN//布尔

                printf(lua_toboolean(L, i) ? "true" : "false");

                break;

            case LUA_TNUMBER//数字

                printf("%g",lua_tonumber(L, i));

                break;

            default:

                printf("%s",lua_typename(L, t));

                break;

        }

        printf("  ");//打印一个分隔符

    }

    printf("\n");//列表结尾

}

void test1()

{

    //创建Lua状态

    lua_State* L = luaL_newstate(); //lua_open();

    //lualib.h还提供了一个luaL_openlibs的方法用于一次性加载所有的标准库。

    luaL_openlibs(L);

    //入栈 bool类型

    lua_pushboolean(L, 1);

    lua_pushnumber(L, 10);

    lua_pushnil(L);

    lua_pushstring(L, "hello");

    //遍历

    stackDump(L);

// idx索引上的值的副本压入栈顶

    lua_pushvalue(L, -4);

    stackDump(L);

//(弹出栈顶元素,并替换索引idx位置的值)lua_replace

    lua_replace(L, 3);

    stackDump(L);    

    lua_settop(L, 6);

    stackDump(L);    

    lua_remove(L, -3);

    stackDump(L);   

    lua_settop(L, -4);

    stackDump(L);

    lua_close(L);

}

true  10  nil  'hello'  
true  10  nil  'hello'  true  
true  10  true  'hello'  
true  10  true  'hello'  nil  nil  
true  10  true  nil  nil  
true  10  

myName="my"

helloTable={name="zhangjia",IQ=225}

function helloAdd(num1,num2)

return num1+num2,num1-num2

end

function hahaAdd(num1,num2,num3)

return num1+num2+num3

end


void  demo1()

{

    lua_State*L=lua_open();

    luaL_openlibs(L);

    //luaL_dofile函数的功能是加载加执行lua文件,成功返回为0,失败为1.

    int error=luaL_dofile(L, "/Users/mac/Desktop/c++/4.26/4.26/ha.lua");

    if (error!=0)

    {

        std::cout<<"ERROR\n"<<std::endl;

    }

    lua_settop(L,0);

    //把全局的name的值压到栈顶。

    lua_getglobal(L, "myName");

    //lua_is*k*(lua_State *L,int index) 检查变量是不是某个类型,index指示变量的顺序,栈顶为-1

    //lua_to***(lua_State *,int index) 获取栈中的变量,然后转换为某个指定的类型,并返回。

    int  isstr=lua_isstring(L, -1);

    printf("%d\n",isstr);

    const char *str=lua_tostring(L, -1);

    printf("%s\n",str);

      lua_close(L);

}运行结果:1 my


myName="my"

helloTable={name="zhangjia",IQ=225}

function helloAdd(num1,num2)

return num1+num2,num1-num2

end

function hahaAdd(num1,num2,num3)

return num1+num2+num3

end


void  demo2()

{

    lua_State*L=lua_open();

    luaL_openlibs(L);

    int error=luaL_dofile(L, "/Users/mac/Desktop/c++/4.26/4.26/ha.lua");

    if (error!=0)

    {

        std::cout<<"ERROR\n"<<std::endl;

    }

    lua_settop(L,0);

    //把全局的name的值压到栈顶。

    {lua_getglobal(L, "helloTable");

//查询

    lua_pushstring(L, "name");

    lua_gettable(L, -2);

        

//         lua_getfield(L, 1, "IQ");  

    int  intr=lua_isstring(L, -1);

    if (intr==0)

    {

        cout<<"没有"<<endl;

    }

    //lua_is*k*(lua_State *L,int index) 检查变量是不是某个类型,index指示变量的顺序,栈顶为-1

    //lua_to***(lua_State *,int index) 获取栈中的变量,然后转换为某个指定的类型,并返回。

    const char *str=lua_tostring(L, -1);

    printf("%s\n",str);

    int top = lua_gettop(L);

        printf("%d",top);

     }


    lua_close(L);

}运行结果: zhangjia 2



void  demo3()

{

    lua_State*L=lua_open();

    luaL_openlibs(L);

    int error=luaL_dofile(L, "/Users/mac/Desktop/c++/4.26/4.26/ha.lua");

    if (error!=0)

    {

        std::cout<<"ERROR\n"<<std::endl;

    }

    lua_settop(L,0);

    

    //把全局的name的值压到栈顶。

    {

//        lua_getglobal(L, "helloTable");

        //新建table

        lua_newtable(L);

        //修改

        lua_pushstring(L, "new");

        lua_setfield(L, 1, "name");

        

        lua_getfield(L, 1, "name");//查询

       

        const char *str=lua_tostring(L, -1);

        printf("%s\n",str);}


    lua_close(L);


}运行结果:new





void  demo4()

{

    lua_State*L=lua_open();

    luaL_openlibs(L);

    int error=luaL_dofile(L, "/Users/mac/Desktop/c++/4.26/4.26/ha.lua");

    if (error!=0)

    {

        std::cout<<"ERROR\n"<<std::endl;

    }

    lua_settop(L,0);

    

    //把全局的name的值压到栈顶。

    {

        lua_getglobal(L, "helloAdd");

       

        lua_pushnumber(L,10);

        lua_pushnumber(L,5);

        lua_call(L, 2, 2);

        int n=lua_gettop(L);

        cout<<n<<endl;

        

        int result1=lua_tonumber(L, -1);

        int result2=lua_tonumber(L, -2);

        cout<<result1<<endl;

        cout<<result2<<endl;

    }

    lua_close(L); 

}运行结果: 2 5 15



static int average12(lua_State *L)

{

    int n=lua_gettop(L);

    double sum=0;

    int  i=1;

    for (; i<=n; i++)

    {

        sum+=lua_tonumber(L, i);

    }

    lua_pushnumber(L, sum/n);

    lua_pushnumber(L, sum);

    return 2;

}

avg,sum =average(10,20,30,40,50);

print("The average is"..avg);

print("The num is"..sum);


void  demo5()

{

    lua_State*L=lua_open();

    luaL_openlibs(L);

    {

        //注册

        lua_register(L, "average",average12);

//        lua_pushcfunction(L, average12);

//        lua_setglobal(L, "average");

    }

    int error=luaL_dofile(L, "/Users/mac/Desktop/c++/4.26/4.26/avg.lua");

    if (error!=0)

    {

        std::cout<<"ERROR\n"<<std::endl;

    }

      lua_close(L);

    

}运行结果:

The average is30

The num is150



static int getNumber(int num1,int num2)

{

    printf("num1=%d,num2=%d",num1,num2);

    return num1-num2;

    

}

static int cpp_GetNumber(lua_State*L)

{

    int num=(int)lua_tonumber(L, -1);

     int num2=(int)lua_tonumber(L, -2);

    printf("num=%d\n",num);

    printf("num2=%d\n",num2);

    lua_pushnumber(L, getNumber(num, num2));

    int back=(int)lua_tonumber(L, -1);

    printf("back=%d\n",back);

    return 1;

}

local num=cpp_GetNumber(10,20);

print(num)


void  demo6()

{

    

    lua_State*L=lua_open();

    luaL_openlibs(L);

    {

        //注册

        lua_register(L, "cpp_GetNumber",cpp_GetNumber);

        //        lua_pushcfunction(L, average12);

        //        lua_setglobal(L, "average");

    }

    int error=luaL_dofile(L, "/Users/mac/Desktop/c++/4.26/4.26/test.lua");

    if (error!=0)

    {

        std::cout<<"ERROR\n"<<std::endl;

    }

  

     lua_close(L);

}运行结果:

num=20

num2=10

num1=20,num2=10back=10

10




#include <iostream>

using namespace std;

class A

{

public:

    int getVar()

    {

        return var;

    }

    void setVar(int v)

    {

        var=v;

    }

private:

    int var=10;

    

};

a=newA()

a:setVar(123)

print(a:getVar())

deleteA(a)


/**********************************c++的类传给Lua**********************************/

//new一个A对象

int newA(lua_State* L)

{

    *(A**)lua_newuserdata(L, sizeof(A*)) = new A();  // lua will manage Student** pointer

    

    luaL_getmetatable(L, "A");

    lua_setmetatable(L, -2);

    return 1;

}

//delete一个A对象

int deleteA(lua_State* L)

{

    delete *(A**)lua_topointer(L, 1);

    return 0;

}

int getVar(lua_State* L)

{

    A* pT = *(A**)lua_topointer(L, 1);

    lua_pushnumber(L, pT->getVar());

    return 1;

}

int setVar(lua_State* L)

{

    A* pT = *(A**)lua_topointer(L, 1);

    int var = (int)lua_tonumber(L, -1);

    pT->setVar(var);

    return 0;

}

//封装了一系列方法之后,就需要把这些方法整合到一个metatable中,也就是相当于这个类的定义。

//Alua成员方法列表

static const struct luaL_reg AFunc[] =

{

    {"getVar",getVar},

    {"setVar",setVar},

    {NULL,NULL}

};

//注册A这个类

void registerA(lua_State* L)

{

    lua_register(L, "newA", newA);

    lua_register(L, "deleteA", deleteA);

    //创建一个名为Ametatable

    luaL_newmetatable(L, "A");

    lua_pushstring(L, "__index");

    lua_pushvalue(L, -2);

    //设置metatable.__index = metatable

    lua_settable(L, -3);

    

    //A的成员方法列表绑定到metatable

    //等同于设置metatablegetVarsetVar字段为对应的C函数

    luaL_openlib(L, NULL, AFunc, 0);

    //另外注册两个函数,供lua创建和释放A对象

    lua_pop(L, 1);

}


void demo7()

{

    lua_State* L = lua_open();

    luaL_openlibs(L);

    lua_settop(L, 0);

    registerA(L);

    int err = luaL_dofile(L,"/Users/mac/Desktop/c++/4.26/4.26/classA.lua");

    if (err != 0) {

        cout<<"error"<<endl;

    }

    lua_close(L);

}运行结果:123


/*

 int luaL_newmetatable (lua_State *L, const char *tname);

 创建新表(将用作 metatable),将新表放到栈顶并建立表和 registry 中类型名的联系

 

 void luaL_getmetatable (lua_State *L, const char *tname);

 获取 registry 中的 tname 对应的 metatable,压入栈中

 

 void *luaL_checkudata (lua_State *L, int index, const char *tname);

 检查在栈中指定位置的对象是否为带有给定名字的 metatable userdata。如果对象不

 存在正确的 metatable,返回 NULL,否则,返回userdata的地址

 

 */




int main(int argc, const char * argv[])

    {

    test1();

//    demo1();

//    demo2();

//     demo3();

//     demo4();

//        demo5();

//        demo6();

//        demo7();

    return 0;

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值