LuaPlus是Lua的C++增强,也就是说,LuaPlus本身就是在Lua的源码上进行增强得来的。用它与C++进行合作,是比较好的一个选择。
LuaPlus目前版本为:LuaPlus for Lua 5.01 Distribution Build 1080 (February 28,2004)。大家可以到
http://luaplus.org/ 站点下载:
源码?? (
http://wwhiz.com/LuaPlus/LuaPlus50_Build1081.zip)
目标码 (
http://wwhiz.com/LuaPlus/LuaPlus50_Build1081_Win32Binaries.zip)
介绍LuaPlus: 好用的Lua For C++扩展????? 沐枫网志
[由于lua内核升级到5.1,因此,luaplus也同样跟着升级。最新的luaplus可以通过svn获取,地址 svn://svn.luaplus.org/LuaPlus/work51,
同时,luaplus基于5.0的内核仍然在维护更新,也可以通过svn获取,地址 svn://svn.luaplus.org/root/LuaPlus/Dev ]
我将在下面说明,如何使用LuaPlus,以及如何更方便的让LuaPlus与C++的类合作无间。
1. 调用Lua脚本
?

????
//
?创建Lua解释器:

????LuaStateOwner?state;?

????

????
//
?执行Lua脚本:

????state
->
DoString(
"
print('Hello?World//n')
"
);

????
//
?载入Lua脚本文件并执行:

????state
->
DoFile(
"
C://test.lua
"
);

????
//
?载入编译后的Lua脚本文件并执行:

????state
->
DoFile(
"
C://test.luac
"
);


2. 与Lua脚本互相调用

????
//
?为Lua脚本设置变量

????state
->
GetGlobals().SetNumber(
"
myvalue
"
,?
123456
);

????
//
?获得Lua变量的值

????
int
?myvalue?
=
?state
->
GetGlobal(
"
myvalue
"
).GetInteger();

????

????
//
?调用Lua函数

????LuaFunction
<
int
>
?luaPrint?
=
?state
->
GetGlobal(
"
print
"
);

????luaPrint(
"
Hello?World/n
"
);

????

????
//
?让Lua调用C语言函数


????
int
?add(
int
?a,?
int
?b)

{?return?a+b;}

????state
->
GetGlobals().RegisterDirect(
"
add
"
,?add);

????state
->
DoString(
"
print(add(3,4))
"
);

????

????
//
?让Lua调用C++类成员函数


????
class
?Test

{public:?int?add(int?a,?int?b)
{return?a+b;}}
;

????Test?test;

????state
->
GetGlobals().RegisterDirect(
"
add
"
,?test,?&Test::add);

????state
->
DoString(
"
print(add(3,4))
"
);

???
3. 在Lua脚本中使用C++类
???
??? 这个稍微有点小麻烦。不过,我包装了一个LuaPlusHelper.h的文件,它可以很轻松的完成这个工作。它的实现也很简单,大家可以从源码上来获得如何用纯LuaPlus实现同样的功能。
??? 不过,这里仍然有一个限制没有解决:不能使用虚成员函数。不过考虑到我们仅是在Lua调用一下C++函数,并不是要将C++完美的导入到Lua,这个限制完全可以接受。
??? 另外,类成员变量不能直接在Lua中访问,可以通过类成员函数来访问(比如SetValue/GetValue之类)。?

//
?下面是一个简单的C++类:????

?
class
?Logger


?

{

?public:

??void?LOGMEMBER(const?char*?message)


??
{

???printf("In?member?function:?%s/n",?message);

??}

?

??Logger()


??
{

???printf("Constructing(%p)
/n",?this);

???v?=?10;

??}

??virtual?~Logger()


??
{

???printf("Destructing(%p)
/n",?this);

??}

?

??Logger(int?n)


??
{

???printf("?--?Constructing[%d](%p)
/n",?n,?this);

??}

??Logger(Logger*?logger)


??
{

???printf("?--?Constructing[%p](%p)
/n",?logger,?this);

???logger->LOGMEMBER("?Call?From?Constructor/n");

??}

??int?SetValue(int?val)


??
{

???v?=?val;

??}

??int?GetValue()


??
{

???return?v;

??}

?public:

??int?v;

?}
;

?

????
//
?导入到Lua脚本:

????LuaClass
<
Logger
>
(state)

???????.create(
"
Logger
"
)?
//
?定义构造函数?Logger::Logger()

???????.create
<
int
>
(
"
Logger2
"
)??
//
?定义构造函数?Logger::Logger(int)

???????.create
<
Logger
*>
(
"
Logger3
"
)?
//
?定义构造函数?Logger::Logger(Logger*)

??????
?.destroy(
"
Free
"
)??
//
?定义析构函数?Logger::~Logger()

???????.destroy(
"
__gc
"
)??
//
?定义析构函数?Logger::~Logger()

???????.def(
"
lm
"
,?
&
Logger::LOGMEMBER)??
//
?定义成员函数?Logger::LOGMEMBER(const?char*)

???????.def(
"
SetValue
"
,?
&
Logger::SetValue)

???????.def(
"
GetValue
"
,?
&
Logger::GetValue);

?

????
//
?在Lua中使用Logger类(1):

????state
->
DoString(

????????
"
l?=?Logger();
"
??
//
?调用构造函数?Logger::Logger()

????????
"
l:lm('Hello?World?1');
"
??
//
?调用成员函数?Logger::LOGMEMBER(const?char*)

????????
"
l:Free();
"
??
//
?调用析构函数?Logger::~Logger()

????????);

?

????
//
?在Lua中使用Logger类(2):

????state
->
DoString(

????????
"
m?=?Logger2(10);
"
?
//
?调用构造函数?Logger::Logger(int)

????????
"
m:lm('Hello?World?2');
"
??
//
?调用成员函数?Logger::LOGMEMBER(const?char*)

????????
"
n?=?Logger3(m);
"
?
//
?调用构造函数?Logger::Logger(Logger*)

????????
"
n:lm('Hello?World?3');
"
??
//
?调用成员函数?Logger::LOGMEMBER(const?char*)

????????
"
m:SetValue(11);
"

????????
"
print(m.GetValue());
"

????????
"
m,n?=?nil,?nil;
"
?
//
?m,n?将由Lua的垃极回收来调用析构函数

????????);


4. 将一组C函数归类到Lua模块
?

????
//
同上面一样,我采用LuaPlusHelper.h来简化:

????LuaModule(state,?
"
mymodule
"
)

???????.def(
"
add
"
,?add)

???????.def(
"
add2
"
,?add);

?

????state
->
DoString(

????????
"
print(mymodule.add(3,4));
"

????????
"
print(mymodule.add2(3,4));
"

????????);


5. 使用Lua的Table数据类型

????
//
?在Lua中创建Table

????LuaObject?table?
=
?state
->
GetGlobals().CreateTable(
"
mytable
"
);

????table.SetInteger(
"
m
"
,?
10
);

????table.SetNumber(
"
f
"
,?
1.99
);

????table.SetString(
"
s
"
,?
"
Hello?World
"
);

????table.SetWString(
"
ch
"
,?L
"
你好
"
);

????table.SetString(
1
,?
"
What
"
);

????

????
//
?相当于Lua中的:

????
//
?mytable?=?{m=10,?f=1.99,?s="Hello?World",?ch=L"你好",?"What"}

??

????
//
?也可以使用table作为key和value:

????state
->
GetGlobals().CreateTable(
"
nexttable
"
)

????????.SetString(table,?
"
Hello
"
)

????????.SetObject(
"
obj
"
,?table);

????
//
?相当于Lua中的:

????
//
?nexttable?=?{mytable="Hello",?obj=mytable}

?

????
//
获得Table的内容:

????LuaObject?t2?
=
?state
->
GetGlobals(
"
mytable
"
);

????
int
?m?
=
?t2.GetByName(
"
m
"
).GetInteger();

????

????LuaObject?t3?
=
?state
->
GetGlobals(
"
nexttable
"
);

????std::
string
?str?
=
?t3.GetByObject(t2).GetString();

???
6? 遍历Table
?

?LuaStateOwner?state;

?state.DoString(?
"
MyTable?=?{?Hi?=?5,?Hello?=?10,?Yo?=?6?}
"
?);

?

?LuaObject?obj?
=
?state.GetGlobals()[?
"
MyTable
"
?];

?
for
?(?LuaTableIterator?it(?obj?);?it;?it.Next()?)


?

{

?????const?char*?key?=?it.GetKey().GetString();

?????int?num?=?it.GetValue().GetInteger();

?}


篇尾
上面我只是简单的举一些例子来说明LuaPlus以及LuaPlusHelper的使用方法,具体文档请参见LuaPlus。
需要下载LuaPlusHelper,请点这里:
http://www.cnblogs.com/Files/ly4cn/LuaPlusHelper.rar
测试程序(VC7.1):
http://www.cnblogs.com/Files/ly4cn/LuaPlusTest.rar