1. lua文件
str = "I am learning lua!"
tbl = {name = "shun", id = 20200501}
function add(a,b)
return a + b
end
//////////////////////////////////////////////////////////////////////////////////////////
2. main.cpp文件
#include
#include
using namespace std;
extern "C"
{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
int main()
{
//1.创建Lua状态
lua_State *L = luaL_newstate();
if (L == NULL)
{
return -1;
}
//2.加载lua文件
int bRet = luaL_loadfile(L,"scripts/testlua.lua");
if(bRet)
{
cout<<"load file error"<
}
//3.运行lua文件
bRet = lua_pcall(L,0,0,0);
if(bRet)
{
cout<<"pcall error"<
}
//4.读取变量 //5.读取table //6.读取函数 //至此,栈中的情况是: //7.关闭state return 0; } 运行结果: 方法一:静态注册 大概顺序就是:在c++中写一个模块函数,将函数注册到lua解释器中,然后由c++去执行我们的lua文件,然后在lua中调用刚刚注册的函数。 avg, sum = average(10, 20, 30, 40, 50) #include extern "C" /* 循环求参数之和 */ int main ( int argc, char *argv[] ) //1.创建Lua状态 /* 载入Lua基本库 */ /* 暂停 */ 执行一下,得到结果: 1. 建立工程 2. 封装C++类 1)CMath.H #ifndef CMATH_H extern "C" class CMath int Sub(int x, int y); }; #ifdef __cplusplus 2) CMath.CPP #include "cmath.h" } cout<<"%p Add="< static int CreateCMath(lua_State* L) static int DestoryCTest(lua_State* L) static int CallAdd(lua_State* L) // 调用C++类方法的跳板函数。 // 调用C++类方法的跳板函数。 // 调用C++类方法的跳板函数。 // 调用C++类方法的跳板函数。 static luaL_Reg arraylib_m [] = { int luaopen_cmath(lua_State *L){ luaL_newmetatable(L, "CMath"); // 创建一个元表 lua_pushstring(L, "__gc"); // 垃圾回收 lua_pushstring(L, "__index"); // lua_pushstring(L, "Add"); // 放元表中增加一个函数。这样所有基于该元表的Table就都有Add方法了 // lua_pop(L,1); #include using namespace std; lua_State *L = luaL_newstate(); luaL_openlibs(L); luaopen_cmath(L); //打开封装的C++lib库 int bRet = luaL_dofile(L, "scripts/testlua.lua"); 4) testlua.lua调用C++方法 --第四步:在lua中调用 cpp_add,cpp_sub直接操作 --print("d.Add(4, 5) ==> " .. d:Add(4, 5)); 5)运行结果 三.总结 lua和c++是通过一个虚拟栈来交互的。 c++调用lua实际上是:由c++先把数据放入栈中,由lua去栈中取数据,然后返回数据对应的值到栈顶,再由栈顶返回c++。 lua调c++也一样:先编写自己的c模块,然后注册函数到lua解释器中,然后由lua去调用这个模块的函数。
lua_getglobal(L,"str");
string str = lua_tostring(L,-1);
cout<<"str = "<
lua_getglobal(L,"tbl");
lua_getfield(L,-1,"name");
str = lua_tostring(L,-1);
cout<<"tbl:name = "<
lua_getglobal(L, "add"); // 获取函数,压入栈中
lua_pushnumber(L, 10); // 压入第一个参数
lua_pushnumber(L, 20); // 压入第二个参数
int iRet= lua_pcall(L, 2, 1, 0);// 调用函数,调用完成以后,会将返回值压入栈中,2表示参数个数,1表示返回结果个数。
if (iRet) // 调用出错
{
const char *pErrorMsg = lua_tostring(L, -1);
cout << pErrorMsg << endl;
lua_close(L);
return -1;
}
if (lua_isnumber(L, -1)) //取值输出
{
double fValue = lua_tonumber(L, -1);
cout << "Result is " << fValue << endl;
}
//=================== 栈顶 ===================
// 索引 类型 值
// 4 int: 30
// 3 string: shun
// 2 table: tbl
// 1 string: I am so cool~
//=================== 栈底 ===================
lua_close(L);二.lua调用c++
主要两个方法实现:
1. 在目录下新建一个testlua.lua如下:
print("The average is ", avg)
print("The sum is ", sum)
2.新建main.cpp如下:
#include
using namespace std;
{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
/* 指向Lua解释器的指针 */
lua_State* L;
static int average(lua_State *L)
{
/* 得到参数个数 */
int n = lua_gettop(L);
double sum = 0;
int i;
for (i = 1; i <= n; i++)
{
/* 求和 */
sum += lua_tonumber(L, i);
}
/* 压入平均值 */
lua_pushnumber(L, sum / n);
/* 压入和 */
lua_pushnumber(L, sum);
/* 返回返回值的个数 */
return 2;
}
{
lua_State *L = luaL_newstate();
if (L == NULL)
{
return -1;
}
luaL_openlibs(L);
/* 注册函数 */
lua_register(L, "average", average);
/* 运行脚本 */
bool bRet = luaL_dofile(L, "scripts/testlua.lua");
if(bRet)
{
cout<<"load file error"<
}
/* 清除Lua */
lua_close(L);
system("pause");
return 0;
}
方法2:绑定C++对象
#define CMATH_H
{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
{
public:
CMath();
virtual ~CMath(){}
void setNum(int x);
int getNum();
int Add(int x, int y);
int Mul(int x, int y);
private:
int num;
extern "C" {
#endif
int luaopen_cmath(lua_State *L);
#ifdef __cplusplus
}
#endif
#endif // CMATH_H
#include "iostream"
using namespace std;
CMath::CMath()
{
void CMath::setNum(int x)
{
num = x;
}
int CMath::getNum()
{
return 0;
}
int CMath::Add(int x, int y)
{
};
int CMath::Sub(int x, int y)
{
return x-y;
}
int CMath::Mul(int x, int y)
{
return x*y;
}
////////////////////////////////////////////////////////////////////////////
{
// 创建一个元表为CTest的Table——Lua对象
*(CMath**)lua_newuserdata(L, sizeof(CMath*)) = new CMath();
luaL_getmetatable(L, "CMath");
lua_setmetatable(L, -2);
return 1;
}
{
// 释放对象
delete *(CMath**)lua_topointer(L, 1);
return 0;
}
{
int cnt = lua_gettop (L);
CMath* pT = *(CMath**)lua_topointer(L, 1);
lua_pushnumber(L, pT->Add(lua_tonumber(L, 2), lua_tonumber(L, 3)));
return 1;
}
static int CallSub(lua_State* L)
{
int cnt = lua_gettop (L);
CMath* pT = *(CMath**)lua_topointer(L, 1);
lua_pushnumber(L, pT->Sub(lua_tonumber(L, 2), lua_tonumber(L, 3)));
return 1;
}
static int CallMul(lua_State* L)
{
int cnt = lua_gettop (L);
CMath* pT = *(CMath**)lua_topointer(L, 1);
lua_pushnumber(L, pT->Mul(lua_tonumber(L, 2), lua_tonumber(L, 3)));
return 1;
}
static int CallgetNum(lua_State* L)
{
int cnt = lua_gettop (L);
// 调用C++类方法的跳板函数。
CMath* pT = *(CMath**)lua_topointer(L, 1);
lua_pushnumber(L, pT->getNum());
return 1;
}
static int CallsetNum(lua_State* L)
{
int cnt = lua_gettop (L);
CMath* pT = *(CMath**)lua_topointer(L, 1);
pT->setNum(lua_tonumber(L, 2));
return 0;
}
{"Add", CallAdd},
{"Sub", CallSub},
{"Mul", CallMul},
{"setNum", CallsetNum},
{"getNum", CallgetNum}, //print(a)时Lua会调用该元方法。
{NULL, NULL}
};
// 往lua中注册类
lua_pushcfunction(L, CreateCMath); // 注册用于创建类的全局函数
lua_setglobal(L, "CMath");
lua_pushvalue(L,-1);
lua_pushcfunction(L, DestoryCTest);
lua_settable(L, -3); // 公共函数调用的实现就在此啊
lua_pushvalue(L, -2); // 注意这一句,其实是将__index设置成元表自己
lua_settable(L, -3);
// lua_pushcfunction(L, CallAdd);
// lua_settable(L, -3);
//
// lua_pushstring(L, "Sub"); // 放元表中增加一个函数。这样所有基于该元表的Table就都有Add方法了
// lua_pushcfunction(L, CallSub);
// lua_settable(L, -3);
//
// lua_pushstring(L, "Mul"); // 放元表中增加一个函数。这样所有基于该元表的Table就都有Add方法了
// lua_pushcfunction(L, CallMul);
// lua_settable(L, -3);
//
// lua_pushstring(L, "setNum"); // 放元表中增加一个函数。这样所有基于该元表的Table就都有Add方法了
// lua_pushcfunction(L, CallsetNum);
// lua_settable(L, -3);
//
// lua_pushstring(L, "getNum"); // 放元表中增加一个函数。这样所有基于该元表的Table就都有Add方法了
// lua_pushcfunction(L, CallgetNum);
// lua_settable(L, -3);
// lua_register(L, "getNum", CallgetNum);
luaL_setfuncs(L,arraylib_m,0);
return 0;
}
3) main.cpp测试函数
#include
#include
int main ( )
{
if (L == nullptr)
{
return -1;
}
if (bRet)
{
cout << "call testlua.lua file failed" << endl;
return -1;
}
lua_close(L);
// waiting for console
cin.get();
return 0;
}
--testlua. lua代码
c = CMath()
d = CMath()
print("c.Add(1, 2) ==> " .. c:Add(1, 2));
print("d.Sub(104, 5) ==> " .. d:Sub(104, 5));
print("d.Mul(104, 5) ==> " .. d:Mul(104, 5));
--c::setNum(23);
print(c:getNum());