热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

tolua++初探(四)

聚合是最常见的构造新类的方式了,另一个是继承。tolua++支持单继承,后面会提到继承的例子。这里先看看怎么将利用了聚合的类导出到lua中。 我的目的是想在Lu


<使用了聚合的类的导出> 聚合是最常见的构造新类的方式了,另一个是继承。tolua++支持单继承,后面会提到继承的例子。这里先看看怎么将利用了聚合的类导出到lua中。 我的目的是想在Lua中使用C++类的实例,而不是在lua中生成C++类实例,所以我在利用tolua++向lua导出类时一般不导出构造函数,这样就无法在lua中生成类实例。 但是为了演示的方便,这个例子中用到的两个简单类CNumber和CMessage仍然导出了构造函数。 另外一个单件(singleton)CTestSystem的构造函数、拷贝构造函数、=操作符都被声明为protected,在向lua导出时只导出了几个方法。你无法在lua中生成它的实例,即便在C++中也不行,只能通过其静态成员函数GetSingleton()获取。 实际的头文件classg.h如下:




#ifndef_CLASSGROUP_H



#define


_CLASSGROUP_H




#include


<


string


.h


>







class


CNumber


...



{


//


tolua_export





public


:



//


tolua_begin





CNumber():m_nNum(


0


)




...



{


}




CNumber(


int


num):m_nNum(num)




...



{

}







~


CNumber()




...



{


}






void


SetNumber(


int


num)




...



{

m_nNum


=


num;

}






int


GetNumber()




...



{



return


m_nNum;

}






int


Add(


int


num)




...



{

m_nNum


+=


num;



return


m_nNum;

}






//


tolua_end





protected


:



int


m_nNum;

}



;


//


tolua_export




//


tolua_begin





class


CMessage




...



{



//


tolua_end





public


:



//


tolua_begin





CMessage()




...



{

strcpy(m_szMessage,


"


initialmessage


"


);

}




CMessage(


char




*


initmsg)




...



{



if


(initmsg)

strncpy(m_szMessage,initmsg,


256


);

}






~


CMessage()




...



{


}






void


SetMessage(


char




*


msg)




...



{



if


(msg)




...



{

strncpy(m_szMessage,msg,


256


);

}




}






char




*


GetMessage()




...



{



return


m_szMessage;

}






void


ShowMessage()




...



{

printf(


"


thismessageisprintedinc++codewhenluacallShowMessage:%s


"


,m_szMessage);

}






//


tolua_end





protected


:



char


m_szMessage[


256


];

}



;


//


tolua_export









class


CTestSystem


...



{



public


:




static


CTestSystem


&


GetSingleton()


...



{


static


CTestSystemsys;


return


sys;}





CNumber


&


GetNumberObj()


...



{


return


m_Number;}





CMessage


&


GetMessageObj()


...



{


return


m_Message;}






protected


:


CTestSystem()


...



{}




CTestSystem(


const


CTestSystem


&


);

CTestSystem


&




operator


=


(


const


CTestSystem


&


rhs);




~


CTestSystem()


...



{}







private


:

CNumberm_Number;

CMessagem_Message;

}



;




#endif



接下来是pkg文件:




$#include


"


classg.h


"







class


CNumber


...



{


//


tolua_export





public


:



//


tolua_begin





CNumber();

CNumber(


int


num);



~


CNumber(


void


);



void


SetNumber(


int


num);



int


GetNumber(


void


);



int


Add(


int


num);



//


tolua_end





}



;


//


tolua_export




//


tolua_begin





class


CMessage




...



{



//


tolua_end





public


:



//


tolua_begin





CMessage(


void


);

CMessage(


char




*


initmsg);



~


CMessage(


void


);



void


SetMessage(


char




*


msg);



char




*


GetMessage();



void


ShowMessage();



//


tolua_end





}



;


//


tolua_export








class


CTestSystem




...



{



static


CTestSystem


&


GetSingleton();

CNumber


&


GetNumberObj();

CMessage


&


GetMessageObj();

}



;



我只导出需要的部分。有点遗憾的是,tolua++的手册中说无法通过"@"修改你要导出的类的名字,这样的话,如果我想在lua中使用另外的名字,就要用别的办法了(文档中说$renaming可以,未试验,存疑)。 驱动部分和之前的例子中类似:




#include


"


classg.h


"



#include


"


lua.hpp


"






int


tolua_classgroup_open(lua_State


*


);




int


_tmain(


int


argc,_TCHAR


*


argv[])




...



{

lua_State


*


L


=


luaL_newstate();

luaopen_base(L);

tolua_classgroup_open(L);

luaL_dofile(L,


"


../scripts/classgroup.lua


"


);

lua_close(L);



return




0


;

}




一直没有介绍上面用到的几个函数。在lua5.1中,用来生成lua状态对象的lua_open函数不再直接可用,替换为lua_newstate,不过lua_newstate要提供内存分配函数,lua扩展库提供了无参数的luaL_newstate,用起来方面。同时为了向前兼容,还做了宏定义#define lua_open luaL_newstate()。所以你仍然可以用lua_open来或者lua_State,但是要注意这里只是个宏。 luaopen_base()打开基本的库。 tolua_classgroup_open是tolua++生成的函数,用来向lua导出你定义的类和其它变量及函数。 luaL_dofile也是宏定义,用来加载并执行一个脚本文件,在lauxlib.h中定义。 lua_close关闭之前打开的状态块。 关于这些函数的详细说明,请参考
lua5.1在线文档
。 下面是classgroup.lua文件:




print(


"


nowinclassgroup.lua!


"


)


print(


"


gettheCTestSystemsingleton,callGetNumberObjandGetMessageObj:


"


)

singleton


=


CTestSystem:GetSingleton();

print(singleton)

numobj


=


singleton:GetNumberObj();

print(numobj)

msgobj


=


singleton:GetMessageObj();

print(msgobj)




--


accessCNumberandCMessage

print(


"


initnumobj'snumber:


"


..numobj:GetNumber());

numobj:SetNumber(


100


);

print(


"


aftercallnumobj:SetNumber(100),changednumber:


"


..numobj:GetNumber())


print(


"


initmsgobj'smessage:


"


..msgobj:GetMessage());

msgobj:SetMessage(


"


Thismessageissetinluascript


"


);

print(


"


newmessage:


"


..msgobj:GetMessage())

msgobj:ShowMessage()



OK,这是个简单的例子,我们只用到了tolua++最基本的东西,进一步的研究学习可以琢磨它的文档。但是我用luaplus想做到这一点,费了不少力气。相对luaplus,tolua++在导出类到lua方面更为方便好用,而luaplus用来访问lua脚本则比tolua++方便(隔离了繁琐的虚拟栈操作)。两个封装的侧重点不同,如果可以结合起来,会非常有趣,双向的访问都很方便。有时间的话我会尝试一下。 接下来会试验一下单继承。 ==**== 刚才试验了下$renaming 可以用。在pkg后加入$renaming CTestSystem @ lSystems,用tolua++编译,然后编译工程,则必须修改classgroup.lua,

将singleton


=


CTestSystem:GetSingleton();改为


singleton


=


lSystems:GetSingleton();。


tolua++初探(四)




推荐阅读
author-avatar
迷-糊-娃娃
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有