zoukankan      html  css  js  c++  java
  • C++实现对lua访问的封装

    这是一个几年前写的对lua的访问封装,当时的项目仅提供了最基本的lua访问接口:调用lua函数,向lua注册标准格式的C++函数.

    本来我想引进luabind,但luabind相对又过于复杂,并不是所有功能都是我需要的,并且还要为此引入庞大boost.最终还是决定

    按需求编写一个简单的封装库.

    首先简单列一下我的需求:

    1)可以注册任意类型的C++函数到lua中

    2)可以方便的调用lua函数,方便的访问lua中的表

    3)可以访问lua中创建的对象,调用lua对象提供的方法

    4)注册C++类型到lua,使lua可以访问C++对象的字段,和函数

    下面介绍一下提供的一些API:

    1)call_luaFunction,用于方便的调用lua函数,使用格式如下:

    int ret = call_luaFunction<int>("funname",L);

    2)register_function,用于向lua注册任意类型的C++函数,例如有如下函数:

    static int showmsg(const char *msg)

    {

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

      return 0;

    }

    则可以这样注册,register_function(L,"show",showmsg);

    3)register_class,register_property,register_member_function用于向lua注册一个C++类型

    4)luaObject,代表lua中的对象,可以通过成员函数CallMemberFunction,SetMemberValue,GetMemberValue

    访问lua对象的方法和成员变量

    5)luatable,代表lua中的表

    6)Interger64用以支持在lua中实现64位整型运算

    这里说明一下,我不想C++对象在lua中被创建,而只能在C++中创建再传递给lua(Interger64是个例外,因为它主要是在lua中被使用的类型),所以register_class

    并没有提供构造函数的注册.

    测试代码:

    #include "luaWrapper.h"
    #include <stdio.h>
    
    static int userdata(lua_State *L)
    {
        int *a = (int*)lua_touserdata(L,-1);
        printf("a = %d\n",*a);
        return 0;
    }
    static int showmsg(const char *msg)
    {
        printf("%s\n",msg);
        return 0;
    }
    
    class testa
    {
    public:
        int vala;
        int valb[10];
    };
    
    class testd
    {
    public:
        virtual void testdf(){}
        int vald;
    };
    
    class testb : virtual public testa,virtual public testd
    {
    public:
        
        virtual void function()
        {
            printf("this is function\n");
        }
    
        int64_t valb;
        double  vald;
    };
    
    class testc : public testb
    {
    public:
        void function()
        {
            printf("this is testc\n");
        }
    
        void functionc()
        {
            printf("functionc\n");
        }
    };
    
    int main()
    {
        luaWrapper lw;
        lw.init();
        lw.load("start.lua");
        lua_State *L = *(&lw);
        //测试注册任意C++函数
        register_function(L,"show",showmsg);
        
        //测试向lua注册C++类
        register_class<testb>(L,"testb");
        register_property("valb",&testb::valb);
        register_property("vald",&testb::vald);
        register_member_function("func",&testb::function);
    
        register_class<testc,testb>(L,"testc");
        register_member_function("funcc",&testc::functionc);
    
        testc tc;
        tc.valb = 1000000000000000002;
        tc.vald = 10.0f;
        testb tb;
        tb.valb = 1000;
        call_luaFunction<void>("test1",L,&tc,(int64_t)1000000000000000001);
        printf("%lld\n",tc.valb);
        printf("%f\n",tc.vald);
        
        luatable ret = call_luaFunction<luatable>("test2",L);
        int i=0;
        printf("{");
        for(;i<ret.size();++i)
        {
            printf("%d,",any_cast<int>(ret[i]));
        }
        printf("}\n");
        
        lua_results<5> ret1 = call_luaFunction<lua_results<5>>("test4",L);
        printf("{");
        for(i=0;i<ret1._rets.size();++i)
        {
            printf("%d,",any_cast<int>(ret1._rets[i]));
        }
        printf("}\n");    
        
        luaObject ac = call_luaFunction<luaObject>("test3",L);
        ac.CallMemberFunction<void>("show");
        printf("balance:%d\n",ac.GetMemberValue<int>("balance"));
        ac.SetMemberValue<int>("balance",1000);
        printf("balance:%d\n",ac.GetMemberValue<int>("balance"));
        luatable lt_in;
        for(int i = 0; i < 5;++i)
            lt_in.push_back(i);
        call_luaFunction<void>("test5",L,lt_in);
        
        call_luaFunction<void>("test6",L,"this is string");    
        
        lt_in.clear();
        lt_in.push_back((const char*)"hello1");
        lt_in.push_back((const char*)"hello2");
        lt_in.push_back((const char*)"hello3");
        lt_in.push_back((const char*)"hello4");
        lt_in.push_back((const char*)"hello5");
        call_luaFunction<void>("test5",L,lt_in);
        getchar();
        return 0;
    }
    Account = {
    balance = 10,
    names=0,
    }
        
    
    function Account:withdraw (v)
          self.balance = self.balance - v
    end
        
    function Account:new (o)
      o = o or {}   
      setmetatable(o, self)
      self.__index = self
      return o
    end
    
    function Account:show()
        print("this is account show")
    end
    
    function Account:getBalance()
        return self.balance
    end
    
    function Account:setBalance(val)
        self.balance = val
    end
    
    function t(tb)
        tb:func()
    end
    
    function test1(tb,i)
        t(tb)
        show("hello world")
        print(tb.valb)
        tb.valb = i64:new(10000003) 
        tb.vald = 1000.2
        print(i)
    end
    
    function test2()
        return {1,2,3,4,5}
    end
    
    function test3()
        account = Account:new();
        account.balance = 100
        account.name = "sniperHW"
        return account
    end
    
    function test4()
        return 1,2,3,4,5
    end
    
    function test5(lt)
        print(lt[1])
        print(lt[2])
        print(lt[3])
        print(lt[4])
        print(lt[5])
    end
    
    function test6(str)
        print(str)
    end

    源代码地址:

    https://github.com/sniperHW/luawrapper

  • 相关阅读:
    js数组和数组去重的几种简单的方法
    nodejs项目的model操作mongo
    canvas画布
    bson
    神奇的东西
    sql与nosql
    mong大牛的blog
    mongo 增删改查
    Mongo配置基础
    session放数据库里解决丢失的问题
  • 原文地址:https://www.cnblogs.com/sniperHW/p/2460643.html
Copyright © 2011-2022 走看看