tolua++初探(四)

前端之家收集整理的这篇文章主要介绍了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( num)

    
{

        m_nNum 
= num;

    }
 GetNumber()

    
{

        
return m_nNum;

    }
 Add( num)

    
+= num;

        
tolua_end    protected m_nNum;

}
; // tolua_export

tolua_begin

 CMessage

{

tolua_end    CMessage()

    
{

        strcpy(m_szMessage, 
"initial message);

    }

    CMessage(
char *initmsg)

    
if(initmsg)

            strncpy(m_szMessage, initmsg,0);">256
CMessage()

    
 SetMessage(msg)

    
(msg)

        
{

            strncpy(m_szMessage, msg,0);">);

        }

    }
GetMessage()

    
 m_szMessage;

    }
 ShowMessage()

    
{

        printf(
this message is printed in c++ code when lua call ShowMessage:%s , m_szMessage);

    }
 m_szMessage[];

}
tolua_export

 CTestSystem :

    
static CTestSystem & GetSingleton(){ CTestSystem sys;  sys;}

    CNumber 
 GetNumberObj() m_Number;}

    CMessage 
 GetMessageObj() m_Message;}:

    CTestSystem()
@H_971_502@...
{}

    CTestSystem(
const CTestSystem);

    CTestSystem 
operator( rhs);

    
CTestSystem()

private:

    CNumber m_Number;

    CMessage m_Message;

}
;

#endif
    接下来是pkg文件
$#include  " classg.h

 CNumber     CNumber();

    CNumber(
 num);

    
CNumber();

    
 GetNumber(

}
 CMessage

    CMessage();

    CMessage(
 initmsg);

    
CMessage(msg);

    
GetMessage();

    
 ShowMessage();

    
 CTestSystem

{

    
 GetSingleton();

    CNumber 
 GetNumberObj();

    CMessage 
 GetMessageObj();

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

#include 
lua.hpp

int  tolua_classgroup_open(lua_State * );

 _tmain(  argc, _TCHAR  argv[])

{

    lua_State 
 L  luaL_newstate();

    luaopen_base(L);

    tolua_classgroup_open(L);

    luaL_dofile(L,0);">../scripts/classgroup.lua
);

    lua_close(L);

    
;

}
    一直没有介绍上面用到的几个函数。在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 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();。

猜你在找的Lua相关文章