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

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

测试代码:

  1 #include "luaWrapper.h"

  2 #include <stdio.h>

  3 

  4 static int userdata(lua_State *L)

  5 {

  6     int *a = (int*)lua_touserdata(L,-1);

  7     printf("a = %d\n",*a);

  8     return 0;

  9 }

 10 static int showmsg(const char *msg)

 11 {

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

 13     return 0;

 14 }

 15 

 16 class testa

 17 {

 18 public:

 19     int vala;

 20     int valb[10];

 21 };

 22 

 23 class testd

 24 {

 25 public:

 26     virtual void testdf(){}

 27     int vald;

 28 };

 29 

 30 class testb : virtual public testa,virtual public testd

 31 {

 32 public:

 33     

 34     virtual void function()

 35     {

 36         printf("this is function\n");

 37     }

 38 

 39     int64_t valb;

 40     double  vald;

 41 };

 42 

 43 class testc : public testb

 44 {

 45 public:

 46     void function()

 47     {

 48         printf("this is testc\n");

 49     }

 50 

 51     void functionc()

 52     {

 53         printf("functionc\n");

 54     }

 55 };

 56 

 57 int main()

 58 {

 59     luaWrapper lw;

 60     lw.init();

 61     lw.load("start.lua");

 62     lua_State *L = *(&lw);

 63     //测试注册任意C++函数

 64     register_function(L,"show",showmsg);

 65     

 66     //测试向lua注册C++类

 67     register_class<testb>(L,"testb");

 68     register_property("valb",&testb::valb);

 69     register_property("vald",&testb::vald);

 70     register_member_function("func",&testb::function);

 71 

 72     register_class<testc,testb>(L,"testc");

 73     register_member_function("funcc",&testc::functionc);

 74 

 75     testc tc;

 76     tc.valb = 1000000000000000002;

 77     tc.vald = 10.0f;

 78     testb tb;

 79     tb.valb = 1000;

 80     call_luaFunction<void>("test1",L,&tc,(int64_t)1000000000000000001);

 81     printf("%lld\n",tc.valb);

 82     printf("%f\n",tc.vald);

 83     

 84     luatable ret = call_luaFunction<luatable>("test2",L);

 85     int i=0;

 86     printf("{");

 87     for(;i<ret.size();++i)

 88     {

 89         printf("%d,",any_cast<int>(ret[i]));

 90     }

 91     printf("}\n");

 92     

 93     lua_results<5> ret1 = call_luaFunction<lua_results<5>>("test4",L);

 94     printf("{");

 95     for(i=0;i<ret1._rets.size();++i)

 96     {

 97         printf("%d,",any_cast<int>(ret1._rets[i]));

 98     }

 99     printf("}\n");    

100     

101     luaObject ac = call_luaFunction<luaObject>("test3",L);

102     ac.CallMemberFunction<void>("show");

103     printf("balance:%d\n",ac.GetMemberValue<int>("balance"));

104     ac.SetMemberValue<int>("balance",1000);

105     printf("balance:%d\n",ac.GetMemberValue<int>("balance"));

106     luatable lt_in;

107     for(int i = 0; i < 5;++i)

108         lt_in.push_back(i);

109     call_luaFunction<void>("test5",L,lt_in);

110     

111     call_luaFunction<void>("test6",L,"this is string");    

112     

113     lt_in.clear();

114     lt_in.push_back((const char*)"hello1");

115     lt_in.push_back((const char*)"hello2");

116     lt_in.push_back((const char*)"hello3");

117     lt_in.push_back((const char*)"hello4");

118     lt_in.push_back((const char*)"hello5");

119     call_luaFunction<void>("test5",L,lt_in);

120     getchar();

121     return 0;

122 }
 1 Account = {

 2 balance = 10,

 3 names=0,

 4 }

 5     

 6 

 7 function Account:withdraw (v)

 8       self.balance = self.balance - v

 9 end

10     

11 function Account:new (o)

12   o = o or {}   

13   setmetatable(o, self)

14   self.__index = self

15   return o

16 end

17 

18 function Account:show()

19     print("this is account show")

20 end

21 

22 function Account:getBalance()

23     return self.balance

24 end

25 

26 function Account:setBalance(val)

27     self.balance = val

28 end

29 

30 function t(tb)

31     tb:func()

32 end

33 

34 function test1(tb,i)

35     t(tb)

36     show("hello world")

37     print(tb.valb)

38     tb.valb = i64:new(10000003) 

39     tb.vald = 1000.2

40     print(i)

41 end

42 

43 function test2()

44     return {1,2,3,4,5}

45 end

46 

47 function test3()

48     account = Account:new();

49     account.balance = 100

50     account.name = "sniperHW"

51     return account

52 end

53 

54 function test4()

55     return 1,2,3,4,5

56 end

57 

58 function test5(lt)

59     print(lt[1])

60     print(lt[2])

61     print(lt[3])

62     print(lt[4])

63     print(lt[5])

64 end

65 

66 function test6(str)

67     print(str)

68 end

 

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