tolua++初探(四)

<使用了聚合的类的导出>      聚合是最常见的构造新类的方式了,另一个是继承。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, "initial message");     }     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("this message is printed in c++ code when lua call ShowMessage:%s ", m_szMessage);     }     //tolua_end protected:     char m_szMessage[256]; } ; // tolua_export class  CTestSystem { public:     static CTestSystem & GetSingleton(){static CTestSystem sys; return sys;}     CNumber & GetNumberObj(){return m_Number;}     CMessage & GetMessageObj(){return m_Message;} protected:     CTestSystem(){}     CTestSystem(const CTestSystem&);     CTestSystem & operator=(const CTestSystem& rhs);     ~CTestSystem(){} private:     CNumber m_Number;     CMessage m_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( " now in classgroup.lua! " ) print( " get the CTestSystem singleton, call GetNumberObj and GetMessageObj: " ) singleton  =  CTestSystem:GetSingleton(); print(singleton) numobj  =  singleton:GetNumberObj(); print(numobj) msgobj  =  singleton:GetMessageObj(); print(msgobj) -- access CNumber and CMessage print( " init numobj's number:  " ..numobj:GetNumber()); numobj:SetNumber( 100 ); print( " after call numobj:SetNumber(100), changed number :  " ..numobj:GetNumber()) print( " init msgobj's message:  " ..msgobj:GetMessage()); msgobj:SetMessage( " This message is set in lua script " ); print( " new message:  " ..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();。

你可能感兴趣的:(c,脚本,lua,文档,扩展)