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

你可能感兴趣的:(C++)