<使用了聚合的類的導出> 聚合是最常見的構(gòu)造新類的方式了,另一個是繼承。tolua++支持單繼承,后面會提到繼承的例子。這里先看看怎么將利用了聚合的類導出到lua中。 我的目的是想在Lua中使用C++類的實例,而不是在lua中生成C++類實例,所以我在利用tolua++向lua導出類時一般不導出構(gòu)造函數(shù),這樣就無法在lua中生成類實例。 但是為了演示的方便,這個例子中用到的兩個簡單類CNumber和CMessage仍然導出了構(gòu)造函數(shù)。 另外一個單件(singleton)CTestSystem的構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)、=操作符都被聲明為protected,在向lua導出時只導出了幾個方法。你無法在lua中生成它的實例,即便在C++中也不行,只能通過其靜態(tài)成員函數(shù)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可以,未試驗,存疑)。 驅(qū)動部分和之前的例子中類似:
#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
;
}
一直沒有介紹上面用到的幾個函數(shù)。在lua5.1中,用來生成lua狀態(tài)對象的lua_open函數(shù)不再直接可用,替換為lua_newstate,不過lua_newstate要提供內(nèi)存分配函數(shù),lua擴展庫提供了無參數(shù)的luaL_newstate,用起來方面。同時為了向前兼容,還做了宏定義#define lua_open luaL_newstate()。所以你仍然可以用lua_open來或者lua_State,但是要注意這里只是個宏。 luaopen_base()打開基本的庫。 tolua_classgroup_open是tolua++生成的函數(shù),用來向lua導出你定義的類和其它變量及函數(shù)。 luaL_dofile也是宏定義,用來加載并執(zhí)行一個腳本文件,在lauxlib.h中定義。 lua_close關閉之前打開的狀態(tài)塊。 關于這些函數(shù)的詳細說明,請參考
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++方便(隔離了繁瑣的虛擬棧操作)。兩個封裝的側(cè)重點不同,如果可以結(jié)合起來,會非常有趣,雙向的訪問都很方便。有時間的話我會嘗試一下。 接下來會試驗一下單繼承。 ==**== 剛才試驗了下$renaming 可以用。在pkg后加入$renaming CTestSystem @ lSystems,用tolua++編譯,然后編譯工程,則必須修改classgroup.lua,
將singleton
=
CTestSystem:GetSingleton();改為
singleton
=
lSystems:GetSingleton();。


































































































































































更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
