luabind-0.9.1在windows、linux下的使用详解及示例
一. 下載
? ? 1.?本篇博客使用的版本為luabind-0.9.1,下載地址:http://download.csdn.net/download/yzf279533105/10109861
二. 編譯
? ? 1. luabind-0.9.1在windows下的編譯請參考:http://blog.csdn.net/yzf279533105/article/details/77828811
? ? 2. luabind-0.9.1在linux下的編譯請參考:http://blog.csdn.net/yzf279533105/article/details/78483160
?
三. 示例代碼下載:
? ? 1. windows下示例代碼下載地址(環(huán)境是win7,VS2008,已編譯出exe,下載后可隨意修改代碼,重新編譯,進行測試):
? ??https://download.csdn.net/download/yzf279533105/10365718
? ???2. linux下示例點下載地址(環(huán)境是centos6.8,gcc4.4.7,已編譯出可執(zhí)行程序,下載后可隨意修改代碼,重新編譯,進行測試。根目錄下有詳細(xì)介紹文檔,根據(jù)文檔里面的步驟進行操作,一定可以運行成功):
? ??http://download.csdn.net/download/yzf279533105/10135089
? ??3. 如有任何疑問,可聯(lián)系本人QQ:279533105,添加時請注明來自CSDN
? ? 4. 2019-04-30有更新,新增加:
? ? ? ? (1)?C++結(jié)構(gòu)體導(dǎo)出lua
? ? ? ? (2)?參數(shù)為對象指針的函數(shù)導(dǎo)出到lua
? ? ? ? 本博客下面的代碼同步了更新,但下載的示例代碼并未更新,望周知
四. 使用(這里對C++和lua的各種交互情景都進行了示例測試)
? ? C++測試代碼如下:
#include <iostream> using namespace std;#include "Lua_VM.h" #include "luabind/luabind.hpp" using namespace luabind;extern "C" {#include "lua.h"#include "lualib.h"#include "lauxlib.h" }// 要導(dǎo)出到lua中的函數(shù) void greet() {cout<<"hello world"<<endl; }// 要導(dǎo)出到lua中的重載函數(shù) int Add(int nNum1, int nNum2) // int版的Add函數(shù) {return nNum1 + nNum2; }string Add(string str1, string str2) // string版的Add函數(shù) {return str1 + str2; }// 要導(dǎo)出到lua中的枚舉 enum enStudentType {enStudentType_Little, // 小學(xué)生enStudentType_Middle, // 初中生enStudentType_High, // 高中生enStudentType_Big, // 大學(xué)生 };// 要導(dǎo)出到lua中的結(jié)構(gòu)體 struct SScore{string name; // 名字int score; // 分?jǐn)?shù) };// 要導(dǎo)出到lua中的類 class CStudent { public:CStudent(string strName, int nAge, int nScore, string strScore){m_strName = strName; // 名字m_nAge = nAge; // 年齡m_nScore = nScore; // 成績(整型)m_strScore = strScore; // 成績(字符串型)m_nID = 123; // IDm_strNickName="dog"; // 綽號m_score.name = "match"; // 成績:數(shù)學(xué)m_score.score = 100; // 成績:數(shù)學(xué),100分m_nPos = 12;} public:enum enStateType{enStateType_Learn, // 學(xué)習(xí)狀態(tài)enStateType_Play, // 玩耍狀態(tài)enStateType_Sleep, // 睡覺狀態(tài)};public:// 獲取名字string GetName(){return m_strName;}// 獲取年齡int GetAge(){return m_nAge;}// 獲取成績(整型)int GetScore(int nNum1, int nNum2){return m_nScore;}// 獲取成績(字符串型)string GetScore(string str1, string str2){return m_strScore;}public:// 設(shè)置位置void SetPos(int nPos){m_nPos = nPos;}// 獲取位置int GetPos(){return m_nPos;} public:// 下面三個屬性導(dǎo)出到luaint m_nID; // IDstring m_strNickName; // 綽號SScore m_score; // 成績 private:string m_strName; // 名字int m_nAge; // 年齡int m_nScore; // 成績(整型)string m_strScore; // 成績(字符串型)int m_nPos; // 位置 };// 要導(dǎo)出到lua中的全局函數(shù),參數(shù)為對象指針 string GetStudentName(CStudent* pStudent) {return pStudent->GetName(); }// 要導(dǎo)出到lua中的繼承類 class CPeople {int sex; // 性別 };class CMan : public CPeople {int nBeard; // 胡須 };// 導(dǎo)出到lua int ExportToLua(lua_State* L) {open(L);// 導(dǎo)出到lua全局表module(L)[// 把全局函數(shù)greet()導(dǎo)出到lua中def("greet", &greet), // 全局函數(shù)(參數(shù)是對象指針)def("GetStudentName", &GetStudentName),// 導(dǎo)出全局函數(shù)greet()也可以這樣寫//LUA_REG_FREE_FUNC(greet),// 把兩個全局的Add()重載函數(shù)導(dǎo)出到lua中def("Add",(int (*) (int, int)) &Add), def("Add",(string (*) (string, string)) &Add)// 導(dǎo)出全局變量// 導(dǎo)出枚舉//enum_("constants")//(// value("enStudentType_Little", enStudentType_Little), // 小學(xué)生// value("enStudentType_Middle", enStudentType_Middle), // 初中生// value("enStudentType_High", enStudentType_High), // 高中生// value("enStudentType_Big", enStudentType_Big) // 大學(xué)生// )];// 導(dǎo)出結(jié)構(gòu)體SScore,雖然SScore是struct,仍要以類的方式進行導(dǎo)出,且需導(dǎo)出構(gòu)造函數(shù),謹(jǐn)記module(L)[class_<SScore>("SScore") // 導(dǎo)出類名字"CStudent".def(constructor<>()) // 導(dǎo)出構(gòu)造函數(shù).def_readwrite("name",&SScore::name) // 導(dǎo)出可讀可寫變量.def_readwrite("score",&SScore::score) // 導(dǎo)出可讀可寫變量];// 導(dǎo)出類CStudentmodule(L)[class_<CStudent>("CStudent") // 導(dǎo)出類名字"CStudent".def(constructor<string,int,int,string>()) // 導(dǎo)出構(gòu)造函數(shù).def("GetName", &CStudent::GetName) // 導(dǎo)出GetName()函數(shù).def("GetAge", &CStudent::GetAge) // 導(dǎo)出GetAge()函數(shù)// LUA_REG_MEM_FUNC(CStudent, GetAge) // 導(dǎo)出GetAge()函數(shù)也可以這樣寫// 導(dǎo)出類中的重載函數(shù),注意寫法.def("GetScore", (int (CStudent::*) (int, int)) &CStudent::GetScore).def("GetScore", (string (CStudent::*) (string, string)) &CStudent::GetScore)// 導(dǎo)出類中的屬性.def_readonly("m_nID", &CStudent::m_nID) // 只讀的屬性.def_readwrite("m_strNickName", &CStudent::m_strNickName) // 可讀可寫的屬性.def_readwrite("m_score", &CStudent::m_score) // 可讀可寫的屬性(結(jié)構(gòu)體類型)// 導(dǎo)出類中的屬性,另外一種辦法.property("m_nPos", &CStudent::GetPos, &CStudent::SetPos) // 導(dǎo)出屬性字段m_nPos到lua,用法有點兒類似C#的get,set// 導(dǎo)出類中的枚舉,注意寫法.enum_("constants")[value("enStateType_Learn", CStudent::enStateType_Learn), // 學(xué)習(xí)狀態(tài)value("enStateType_Play", CStudent::enStateType_Play), // 玩耍狀態(tài)value("enStateType_Sleep", CStudent::enStateType_Sleep) // 睡覺狀態(tài)]];// 要導(dǎo)出到lua的繼承類module(L)[class_<CPeople>("CPeople"),class_<CMan, CPeople>("CMan") // 標(biāo)明繼承關(guān)系,即CMan繼承自CPeople// 如果不指定類的繼承關(guān)系, LuaBind 將不能在相關(guān)的繼承類型間進行隱式類型轉(zhuǎn)換];return 0; }// 訪問lua中的函數(shù),變量,table等 void TestLua(lua_State* L) {printf("\n---------- C++開始訪問lua中的函數(shù),變量,table ------------\n");LUA_CODE_BEGIN// 訪問lua中的add函數(shù) int nAddResult = luabind::call_function<int>(L,"add", 2, 3);printf("訪問lua的全局函數(shù)add(),nAddResult = %d\n\n", nAddResult);// 訪問lua中的整型全局變量int nValue = luabind::object_cast<int>(luabind::globals(L)["nGlobalValue"]);printf("訪問lua的整型全局變量nGlobalValue = %d\n\n", nValue);// 訪問lua中的字符串型全局變量string strValue = luabind::object_cast<string>(luabind::globals(L)["strGlobalValue"]);printf("訪問lua的字符串型全局變量strGlobalValue = %s\n\n", strValue.c_str());// 訪問lua中的table型全局變量// 先獲取該tableluabind::object tTable = luabind::globals(L)["globalTable"];printf("訪問lua的table型全局變量globalTable\n");// 判斷類型是否為tableif (type(tTable) == LUA_TTABLE){// 再獲取該table中的字符串型字段string strName = luabind::object_cast<string>(tTable["name"]);printf("訪問lua的table型全局變量globalTable中的字段name = %s\n",strName.c_str());// 再獲取該table中的整型字段int nAge = luabind::object_cast<int>(tTable["age"]);printf("訪問lua的table型全局變量globalTable中的字段age = %d\n\n",nAge);}// 調(diào)用尾調(diào)用的lua函數(shù),測試堆棧printf("調(diào)用lua出錯時的堆棧信息\n");printf("可以看到打印出了錯誤信息 attempt to perform arithmetic on global 'notExistVar' <a nil value>\n");printf("但未能打印出全部的調(diào)用堆棧,因為發(fā)生了尾調(diào)用,堆棧被清空了");luabind::call_function<int>(L,"functionA",12,34);LUA_CODE_END_VOID_RETURN // 由于本函數(shù)無返回值,所以用無返回值的宏 }void main() {// C++函數(shù),變量,枚舉在lua中的測試 ///// 把指定的C++的函數(shù),類,屬性,枚舉導(dǎo)出到lua中ExportToLua(LUA_VM.pL());// 在lua中訪問這些C++的函數(shù),變量,在test.lua中進行測試LUA_VM.do_file("test.lua");/ lua函數(shù),變量,table在C++中的測試 TestLua(LUA_VM.pL());// 結(jié)束getchar(); }特別注意:編譯上面的C++代碼時需設(shè)置宏LUABIND_DYNAMIC_LINK,否則在導(dǎo)出類的屬性時會被認(rèn)為是函數(shù)。。。。。
添加預(yù)編譯宏的方法,如下圖所示:
原因見參考:https://stackoverflow.com/questions/14887246/how-to-get-luabind-properties-to-work
lua測試代碼如下:
--------------------------------------------------------------- 下里是lua訪問C++導(dǎo)出的內(nèi)容 ---------------------------------------------------------------- -- 調(diào)用c++中的全局函數(shù) print("call C++ global function") greet()----------------------------------------------------------------------------------------- 調(diào)用C++中的重載函數(shù) print("\ncall C++ Add(int,int) function") local nResult = Add(11, 88) -- 調(diào)用int版的Add函數(shù) print("nResult = "..nResult)print("\ncall C++ Add(string,string) function") local strResult = Add("123", "456") -- 調(diào)用string版的Add函數(shù) print("strResult = "..strResult)print("\ncall C++ enum") -- 調(diào)用C++中的全局枚舉 --print("enStudentType_Little = "..enStudentType_Little)--------------------------------------------------------------------------------------- -- 實例化C++中的類 print("\ncreate a C++ class CStudent") local student = CStudent("xiaoming", 8, 90, "good")print("\nglobal function param is Class pointer") local studentName = GetStudentName(student) -- 調(diào)用全局函數(shù)(函數(shù)參數(shù)是對象指針的) print("GetStudentName = "..studentName)print("\ncall CStudent function") local nName = student:GetName() -- 調(diào)用類的一般函數(shù) print("nName = "..nName) local nAge = student:GetAge() -- 調(diào)用類的一般函數(shù) print("nAge = "..nAge)print("\ncall CStudent::GetScore(int,int) function") local nScore = student:GetScore(8,9) -- 調(diào)用類的重載函數(shù)int GetScore(int, int) print("nScore = "..nScore)print("\ncall CStudent::GetScore(string,string) function") local strScore = student:GetScore("math","music") --調(diào)用類的重載函數(shù)string GetScore(string, string) print("strScore = "..strScore)print("\ncall CStudent::m_nID readonly property") print(type(student.m_nID)) print(student.m_nID) -- 訪問類的只讀屬性 --student.m_nID = 456 -- 修改該屬性(這行程序會報錯,暫時注釋掉,如果打開可看到報錯信息"property 'm_nID' is read only")print("\ncall CStudent::m_strNickName readwrite property") print("student.m_strNickName "..student.m_strNickName) -- 訪問類的可讀可寫屬性 student.m_strNickName = "cat" -- 修改該屬性 print("student.m_strNickName "..student.m_strNickName) -- 查看修改結(jié)果print("\ncall CStudent::m_score(struct) readwrite property") print(student.m_score.name) -- 訪問類的可讀可寫屬性 print(student.m_score.score) -- 訪問類的可讀可寫屬性print("\ncall cstudent::m_nPos property") print("student.m_nPos "..student.m_nPos) -- 這會觸發(fā)c++的getpos() student.m_nPos = 34 -- 這會觸發(fā)c++的setpos() print("student.m_nPos "..student.m_nPos)print("\ncall CStudent.enStateType_Learn enum") print("CStudent.enStateType_Learn enum = "..CStudent.enStateType_Learn) -- 調(diào)用類中的枚舉(注意寫法,類的枚舉屬于類,不屬于類的實例) CStudent.enStateType_Learn = 987 -- 嘗試修改C++中的枚舉 print("CStudent.enStateType_Learn enum = "..CStudent.enStateType_Learn) -- 再次打印出來,發(fā)現(xiàn)這個枚舉值真的被修改了,無語。。。。--------------------------------------------------------------- 下面是C++訪問lua的內(nèi)容 ------------------------------------------------------------------- -- 全局函數(shù) function add(nNum1, nNum2)return nNum1 + nNum2 end-- 整型全局變量 nGlobalValue = 54321-- 字符串型全局變量 strGlobalValue = "test global value"-- table型全局變量 globalTable = {name = "xiaohong",age = 6, }-- 測試lua出錯時打印出調(diào)用堆棧 function functionA(nNum)return functionB(nNum) endfunction functionB(nNum)return functionC(nNum) endfunction functionC(nNum)return notExistVar+nNum -- 訪問一個不存在的變量 end測試結(jié)果如下:
?
?
總結(jié)
以上是生活随笔為你收集整理的luabind-0.9.1在windows、linux下的使用详解及示例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux centos 编译luabi
- 下一篇: C++实现反射