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脚本
2. 与Lua脚本互相调用
3. 在Lua脚本中使用C++类
这个稍微有点小麻烦。不过,我包装了一个LuaPlusHelper.h的文件,它可以很轻松的完成这个工作。它的实现也很简单,大家可以从源码上来获得如何用纯LuaPlus实现同样的功能。
不过,这里仍然有一个限制没有解决:不能使用虚成员函数。不过考虑到我们仅是在Lua调用一下C++函数,并不是要将C++完美的导入到Lua,这个限制完全可以接受。
另外,类成员变量不能直接在Lua中访问,可以通过类成员函数来访问(比如SetValue/GetValue之类)。
4. 将一组C函数归类到Lua模块
5. 使用Lua的Table数据类型
6 遍历Table
篇尾
上面我只是简单的举一些例子来说明LuaPlus以及LuaPlusHelper的使用方法,具体文档请参见LuaPlus。
需要下载LuaPlusHelper,请点这里:
http://files.cnblogs.com/ly4cn/LuaPlusHelper.rar
#pragma once #include "luaplus.h" #include <string> class LuaConvert { public: LuaConvert(LuaObject& obj) : refobj(obj) { } operator int() { return refobj.GetInteger(); } operator float() { return refobj.GetFloat(); } operator double() { return refobj.GetDouble(); } operator const char* () { return refobj.GetString(); } operator const wchar_t* () { return refobj.GetWString(); } operator std::string() { return std::string(refobj.GetString()); } operator std::wstring() { return std::wstring(refobj.GetWString()); } operator void* () { return refobj.GetUserData(); } template<typename T> operator T* () { return (T*)refobj.GetUserData(); } template<typename R> operator LuaFunction<R> () { return LuaFunction<R>(refobj); } private: LuaObject refobj; }; template<typename Object> class LuaConstructor { private: static int ConstructorHelper(LuaState* state,Object* pObj) { std::string Metaname("MetaClass_"); Metaname += typeid(Object).raw_name(); LuaObject obj = state->BoxPointer(pObj); obj.SetMetaTable(state->GetGlobal(Metaname.c_str())); obj.PushStack(); return 1; } public: static int Constructor(LuaState* state) { return ConstructorHelper(state,new Object()); } template<typename A1> static int Constructor(LuaState* state) { LuaConvert a1 = LuaObject(state,1); return ConstructorHelper(state,new Object((A1)a1) ); } template<typename A1,typename A2> static int Constructor(LuaState* state) { LuaConvert a1 = LuaObject(state,1); LuaConvert a2 = LuaObject(state,2); return ConstructorHelper(state,new Object((A1)a1,(A2)a2) ); } template<typename A1,typename A2,typename A3> static int Constructor(LuaState* state) { LuaConvert a1 = LuaObject(state,2); LuaConvert a3 = LuaObject(state,3); return ConstructorHelper(state,(A2)a2,(A3)a3) ); } template<typename A1,typename A3,typename A4> static int Constructor(LuaState* state) { LuaConvert a1 = LuaObject(state,3); LuaConvert a4 = LuaObject(state,4); return ConstructorHelper(state,(A3)a3,(A4)a4) ); } template<typename A1,typename A4,typename A5> static int Constructor(LuaState* state) { LuaConvert a1 = LuaObject(state,4); LuaConvert a5 = LuaObject(state,5); return ConstructorHelper(state,(A4)a4,(A5)a5) ); } static int Destructor(LuaState* state) { LuaObject o(state,1); delete (Object*)state->UnBoxPointer(1); LuaObject Meta = state->GetGlobal("MetaClass_Nil"); if(Meta.IsNil()) { Meta = state->GetGlobals().CreateTable("MetaClass_Nil"); } o.SetMetaTable(Meta); return 0; } }; template<typename Object> class LuaClass { public: LuaClass(LuaState* state) { luaGlobals = state->GetGlobals(); std::string Metaname("MetaClass_"); Metaname += typeid(Object).raw_name(); MetaTableObj = luaGlobals.CreateTable(Metaname.c_str()); MetaTableObj.Setobject("__index",MetaTableObj); //MetaTableObj.Register("__gc",&Destructor); //MetaTableObj.Register("Free",&Destructor); } template<typename Func> inline LuaClass& def(const char* name,Func func) { MetaTableObj.RegisterObjectDirect(name,(Object*) 0,func); return *this; } inline LuaClass& create(const char* name) { luaGlobals.Register(name,LuaConstructor<Object>::Constructor); return *this; } template<typename A1> inline LuaClass& create(const char* name) { luaGlobals.Register(name,LuaConstructor<Object>::Constructor<A1>); return *this; } template<typename A1,typename A2> inline LuaClass& create(const char* name) { luaGlobals.Register(name,LuaConstructor<Object>::Constructor<A1,A2>); return *this; } template<typename A1,typename A3> inline LuaClass& create(const char* name) { luaGlobals.Register(name,A2,A3>); return *this; } template<typename A1,typename A4> inline LuaClass& create(const char* name) { luaGlobals.Register(name,A3,A4>); return *this; } template<typename A1,typename A5> inline LuaClass& create(const char* name) { luaGlobals.Register(name,A4,A5>); return *this; } inline LuaClass& destroy(const char* name) { MetaTableObj.Register(name,LuaConstructor<Object>::Destructor); return *this; } private: LuaObject MetaTableObj; LuaObject luaGlobals; }; class LuaModule { public: LuaModule(LuaState* state) { luaModuleObj = state->GetGlobals(); } LuaModule(LuaState* state,const char* name) { luaModuleObj = state->GetGlobals().CreateTable(name); } template<typename Func> inline LuaModule& def(const char* name,Func func) { luaModuleObj.RegisterDirect(name,func); return *this; } template<typename Object,typename Func> inline LuaModule& def(const char* name,Object& o,o,func); return *this; } private: LuaObject luaModuleObj; };
测试程序(VC7.1):
http://files.cnblogs.com/ly4cn/LuaPlusTest.rar
// LuaCppWrapper.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "LuaPlusHelper.h" void LOG(const char* message) { printf("In global function: %s\n",message); } class Logger { public: void LOGMEMBER(const char* message) { printf("In member function: %s\n",message); } virtual void LOGVIRTUAL(const char* message) { printf("In virtual 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("-- 0000---0000\n"); } public: int v; }; void LOG2(const char* message,LuaObject xlogger) { Logger* logger = (Logger*)xlogger.GetUserData(); printf("In global function: %s\n",message); printf("---%d\n",logger->v); logger->LOGMEMBER(message); } int _tmain(int argc,_TCHAR* argv[]) { { LuaStateOwner state; Logger logger; LuaModule(state) .def("LOG",LOG) .def("LOGMEMBER",&Logger::LOGMEMBER) .def("LOGVIRTUAL",&Logger::LOGVIRTUAL) .def("LOG2",LOG2); LuaClass<Logger>(state) .create("Logger") .create<int>("Logger2") .create<Logger*>("Logger3") .destroy("Free") .destroy("__gc") .def("lm",&Logger::LOGMEMBER) .def("lv",&Logger::LOGVIRTUAL); state->GetGlobals().SetNumber("a",123456); int a = state->GetGlobal("a").GetInteger(); printf(" a = %d\n",a); state->DoString("LOG('Hello')"); state->DoString("LOGMEMBER('Hello')"); state->DoString("LOGVIRTUAL('Hello')"); state->DoString( "print('=========');" "print(Logger,_G['MetaClass_.?AVLogger@@']);" "l = Logger();" ); state->DoString( "print(l);" "print(l.lv);" "print(l.lm);" ); state->DoString("print('=========');"); state->DoString("l:lm('Hhhhh');"); //state->DoString("l:lv('Eeeee');"); //--虚函数不能用!!! state->DoString("--l:Free();l=nil;"); state->DoString("print('=========');"); state->DoString("LOG2('SSSS',l)"); state->DoString("print('=========');"); state->DoString("k = Logger2(10);k:lm('World2');k:Free();"); state->DoString("print('=========',l);"); state->DoString("h = Logger3(l);h:lm('World!!!!!!!!!');"); LuaFunction<int> l = state->GetGlobal("LOG"); l("ddddDD"); } system("Pause"); return 0; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。