tolua++初探(四)

系统 1683 0
<使用了聚合的类的导出> 聚合是最常见的构造新类的方式了,另一个是继承。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++初探(四)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论