1. 原理
基本原理就是在C++和lua之间维护一个栈,将各自需要的变量和传给对方的变量放入栈中,进行相互调用。
-
VS2017搭建C++和lua的交互环境
打开 项目属性—VC++ 目录,包含目录、库目录依次添加lua安装目录下的include路径、lua安装目录下的lib路径 -
打开 项目属性—连接器—输入,在附加依赖项中添加lua安装目录下lib文件夹中的.lib文件
以下测试都是在lua5.1中进行的。
1. C++ 调用lua
lua文件
-- test.lua
print("hello, lua")
myStr = "this is a string"
myTable =
{
name = "table",
id = 111,
}
function lua_Add(a, b)
return a+b
end
C++文件
#include <iostream>
#include <string>
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
using namespace std;
int main()
{
//初始化栈
lua_State *L = luaL_newstate();
//加载lua相关库
luaL_openlibs(L);
//加载和执行lua文件
luaL_dofile(L, "lua/test.lua");
//读取值
{
lua_getglobal(L, "myStr");
string str = lua_tostring(L, -1);
lua_pop(L, -1);
cout << "lua myStr is: " << str << endl;
}
//按照栈的存取
//读取表方式1
{
cout << "---------读取表方式1------------------" << endl;
lua_getglobal(L, "myTable");
lua_getfield(L, -1, "name");
string tableName = lua_tostring(L, -1);
cout << "lua myTable.name is : " << tableName << endl;
lua_getfield(L, -2, "id");
int tableId = lua_tonumber(L, -1);
cout << "lua myTable.id is : " << tableId << endl;
}
//读取表方式2
{
cout << "---------读取表方式2------------------" << endl;
lua_getglobal(L, "myTable");
lua_pushstring(L, "name");
lua_gettable(L, -2);
string tableName = lua_tostring(L, -1);
cout << "lua myTable.name is : " << tableName << endl;
lua_pushstring(L, "id");
lua_gettable(L, -3);
int tableId = lua_tonumber(L, -1);
cout << "lua myTable.id is : " << tableId << endl;
}
//设置表方式1
{
cout << "---------设置表方式1------------------" << endl;
lua_getglobal(L, "myTable");
lua_pushnumber(L, 1234);
lua_setfield(L, -2, "id"); //会自动把设置的值出栈,所以现在栈顶是table
lua_getfield(L, -1, "id");
int tableId = lua_tonumber(L, -1);
cout << "lua myTable.id is : " << tableId << endl;
}
//设置表方式2
{
cout << "---------设置表方式2------------------" << endl;
lua_getglobal(L, "myTable");
lua_pushstring(L, "name");
lua_pushstring(L, "newName");
lua_settable(L, -3); //会自动把设置的值出栈,所以现在栈顶是table
lua_getfield(L, -1, "name");
string tableName = lua_tostring(L, -1);
cout << "lua myTable.name is : " << tableName << endl;
}
//调用lua函数
{
lua_getglobal(L, "lua_Add");
lua_pushnumber(L, 1);
lua_pushnumber(L, 2);
lua_pcall(L, 2, 1, 0); //执行函数,2个参数,1个返回值
int res = lua_tonumber(L, -1);
cout << "a + b = " << res << endl;
}
lua_close(L);
return 0;
}
2. lua调用C++
2.1 静态调用
Lua
-- test.lua
print("hello, lua")
print("cpp_add res is :", cpp_add(1, 2))
C++
#include <iostream>
#include <string>
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
using namespace std;
//c++里的函数
int add(int a, int b)
{
return a + b;
}
//定义标准函数
int cpp_add(lua_State *L)
{
int a = lua_tonumber(L, -1);
int b = lua_tonumber(L, -2);
int res = add(a, b);
lua_pushnumber(L, res);
return 1;
}
extern "C" int lua_regist_function(lua_State *L)
{
lua_register(L, "cpp_add", cpp_add);
return 1;
}
int main()
{
//初始化栈
lua_State *L = luaL_newstate();
//加载lua相关库
luaL_openlibs(L);
//注册函数到lua中
lua_regist_function(L);
//加载和执行lua文件
luaL_dofile(L, "lua/test.lua");
lua_close(L);
return 0;
}
2.2 动态库调用
lua
--require("luaFunctions")
-- test.lua
print("hello, lua")
print("cpp_add res is :", luaFunctions.cpp_add(1, 2))
C++
#include <iostream>
#include <string>
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
using namespace std;
//c++里的函数
int add(int a, int b)
{
return a + b;
}
//定义标准函数
int cpp_add(lua_State *L)
{
int a = lua_tonumber(L, -1);
int b = lua_tonumber(L, -2);
int res = add(a, b);
lua_pushnumber(L, res);
return 1;
}
luaL_reg luaFunctions[] =
{
{ "cpp_add", cpp_add},
{ NULL, NULL},
};
extern "C" int lua_register_function(lua_State *L)
{
//luaL_newlib(L, luaFunctions);
luaL_register(L, "luaFunctions", luaFunctions); //5.1以后就废除了,会生成全局变量
return 1;
}
int main()
{
//初始化栈
lua_State *L = luaL_newstate();
//加载lua相关库
luaL_openlibs(L);
//注册函数到lua中
lua_register_function(L);
//加载和执行lua文件
luaL_dofile(L, "lua/test.lua");
lua_close(L);
return 0;
}