首页 > 代码库 > C++实现对lua访问的封装

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 end10     11 function Account:new (o)12   o = o or {}   13   setmetatable(o, self)14   self.__index = self15   return o16 end17 18 function Account:show()19     print("this is account show")20 end21 22 function Account:getBalance()23     return self.balance24 end25 26 function Account:setBalance(val)27     self.balance = val28 end29 30 function t(tb)31     tb:func()32 end33 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.240     print(i)41 end42 43 function test2()44     return {1,2,3,4,5}45 end46 47 function test3()48     account = Account:new();49     account.balance = 10050     account.name = "sniperHW"51     return account52 end53 54 function test4()55     return 1,2,3,4,556 end57 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 end65 66 function test6(str)67     print(str)68 end

 

C++实现对lua访问的封装