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; }
oid 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();。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值