C++调用lua函数

C++ 调用Lua全局变量(普通)

cpp 复制代码
	lua_getglobal(lua, "width");
	int width = lua_tointeger(lua,-1);
	lua_pop(lua,1);
	std::cout << width << std::endl;
	lua_close(lua);

这几行代码要放到lua_pcall(lua, 0,0,0);之后才可以.

C++给lua传递变量

cpp 复制代码
	lua_pushstring(lua, "Hello");
	lua_setglobal(lua, "test");

这几行要放到lua_pcall(lua, 0,0,0);之前,要不lua调不到test这个变量的值.

C++ 调用Lua全局变量表

cpp 复制代码
	lua_getglobal(lua,"conf");
	lua_getfield(lua, -1, "titlename");
	std::cout << lua_tostring(lua,-1) << std::endl;
	lua_pop(lua, 1);
	lua_getfield(lua,-1,"height");
	std::cout << lua_tointeger(lua, -1) << std::endl;
	lua_pop(lua, 1);

C++给lua传递表

cpp 复制代码
	/*C++给lua传入普通表*/
	lua_newtable(lua);
	lua_pushstring(lua,"name");
	lua_pushstring(lua,"xiaoming");
	lua_settable(lua,-3);
	lua_pushstring(lua,"age");
	lua_pushinteger(lua,20);
	lua_settable(lua, -3);
	lua_setglobal(lua, "person");

C++ 调用lua函数

cpp 复制代码
	/*C++ 调用 Lua函数 */
	lua_getglobal(lua, "event");
	/*
	//第一个参数lua的状态,
	第二个参数是传递给 Lua 函数的参数数量,
	第三个参数 Lua 函数中返回的结果数量,
	第四个参数这是错误处理函数在堆栈中的索引。如果在调用 Lua 函数时发生了错误,Lua 将调用此错误处理函数。
	如果不需要错误处理函数,可以将其设置为 0。
	*/
	lua_pcall(lua, 0, 0, 0); 

lua

cpp 复制代码
function event()
	print("C++ call lua")
end

优化:

cpp 复制代码
	/*C++ 调用 Lua函数 */
	std::cout << "top is = " << lua_gettop(lua) << std::endl; //检查堆栈是否有泄露
	lua_getglobal(lua, "event");
	/*
	//第一个参数lua的状态,
	第二个参数是传递给 Lua 函数的参数数量,
	第三个参数 Lua 函数中返回的结果数量,
	第四个参数这是错误处理函数在堆栈中的索引。如果在调用 Lua 函数时发生了错误,Lua 将调用此错误处理函数。
	如果不需要错误处理函数,可以将其设置为 0。
	*/
	if (lua_pcall(lua, 0, 0, 0) != 0)
	{	
		std::cout << "call event failed" << lua_tostring(lua, -1) << std::endl;
		lua_pop(lua,1);
	}

	std::cout << "top is = " << lua_gettop(lua) << std::endl;

C++ 调用lua函数,传递参数并接收返回值

cpp 复制代码
	/*C++ 调用 Lua函数 */
	std::cout << "top is = " << lua_gettop(lua) << std::endl;
	lua_getglobal(lua, "event");
	lua_pushstring(lua,"key"); // 传入参数
	/*
	//第一个参数lua的状态,
	第二个参数是传递给 Lua 函数的参数数量,
	第三个参数 Lua 函数中返回的结果数量,
	第四个参数这是错误处理函数在堆栈中的索引。如果在调用 Lua 函数时发生了错误,Lua 将调用此错误处理函数。
	如果不需要错误处理函数,可以将其设置为 0。
	*/
	if (lua_pcall(lua, 1, 1, 0) != 0)
	{	
		std::cout << "call event failed" << lua_tostring(lua, -1) << std::endl;
		lua_pop(lua,1);
	}
	else
	{
		std::cout << "lua return = " << lua_tostring(lua, -1) << std::endl;
		lua_pop(lua, 1);
	}
	std::cout << "top is = " << lua_gettop(lua) << std::endl;

lua

Lua 复制代码
function event(str)
	print("C++ call lua")
	print("str = " .. str)
	return "1234"
end

添加lua错误处理

cpp 复制代码
	/*C++ 调用 Lua函数 */
	std::cout << "top is = " << lua_gettop(lua) << std::endl;
	int errfun = lua_gettop(lua);
	lua_getglobal(lua, "ferror");
	errfun++;
	lua_getglobal(lua, "event");
	lua_pushstring(lua,"key"); // 传入参数	
	
	/*
	//第一个参数lua的状态,
	第二个参数是传递给 Lua 函数的参数数量,
	第三个参数 Lua 函数中返回的结果数量,
	第四个参数这是错误处理函数在堆栈中的索引。如果在调用 Lua 函数时发生了错误,Lua 将调用此错误处理函数。
	如果不需要错误处理函数,可以将其设置为 0。
	*/
	if (lua_pcall(lua, 1, 1, errfun) != 0)
	{	
		std::cout << "call event failed" << lua_tostring(lua, -1) << std::endl;
		lua_pop(lua,1);
	}
	else
	{
		std::cout << "lua return = " << lua_tostring(lua, -1) << std::endl;
		lua_pop(lua, 1);
	}
	lua_pop(lua, 1);
	std::cout << "top is = " << lua_gettop(lua) << std::endl;

Lua

Lua 复制代码
function ferror(e)
	print("ferror = " .. e)
	return "lua change error"
end

function event1(str)
	print("C++ call lua")
	print("str = " .. str)
	return "1234"
end

结果:

C++给lua传表参数,C++接收表参数

cpp 复制代码
	/*lua给C++传入表*/
	lua_getglobal(lua,"conf");
	lua_getfield(lua, -1, "titlename");
	std::cout << lua_tostring(lua,-1) << std::endl;
	lua_pop(lua, 1);
	lua_getfield(lua,-1,"height");
	std::cout << lua_tointeger(lua, -1) << std::endl;
	lua_pop(lua, 1);
	/*C++ 调用 Lua函数 */
	std::cout << "top is = " << lua_gettop(lua) << std::endl;
	int errfun = lua_gettop(lua);
	lua_getglobal(lua, "ferror");
	errfun++;
	lua_getglobal(lua, "event");
	lua_pushstring(lua,"key"); // 传入参数	
	
	lua_newtable(lua);
	lua_pushstring(lua,"name");
	lua_pushfstring(lua,"xiaoming");
	lua_settable(lua, -3);

	/*
	//第一个参数lua的状态,
	第二个参数是传递给 Lua 函数的参数数量,
	第三个参数 Lua 函数中返回的结果数量,
	第四个参数这是错误处理函数在堆栈中的索引。如果在调用 Lua 函数时发生了错误,Lua 将调用此错误处理函数。
	如果不需要错误处理函数,可以将其设置为 0。
	*/
	if (lua_pcall(lua, 2, 1, errfun) != 0)
	{	
		std::cout << "call event failed" << lua_tostring(lua, -1) << std::endl;
		lua_pop(lua,1);
	}
	else
	{
		lua_getfield(lua, -1,"id");
		std::cout << "lua return tab= " << lua_tointeger(lua, -1) << std::endl;
		lua_pop(lua, 1);
	}
	lua_pop(lua, 2);
	std::cout << "top is = " << lua_gettop(lua) << std::endl;

lua

Lua 复制代码
function event(str,tab)
	print("C++ call lua")
	print("str = " .. str)
	print("tab = " .. tab.name)
	local re = {id=123}
	return re
end

全部代码:

lua

Lua 复制代码
--CTest()

--CTestToString("lua string",123456,true)
--local arr = {"A001","A002","A003"};
--CTestArr(arr)
--local tab = {name="xiaoming",age="22",id="007"};
--CTestTable(tab)

--local re = TestRe()
--print("re = " .. re)

--local retab = TestReTable()
--print("name = " .. retab["name"])
--print("name = " .. retab["age"])


width = 1920
print(test)

conf = 
{
	titlename = "first lua",
	height = 1080
}

print("person is name = " .. person["name"])
print("person is age = " .. person.age)

function ferror(e)
	print("ferror = " .. e)
	return "lua change error"
end

function event(str,tab)
	print("C++ call lua")
	print("str = " .. str)
	print("tab = " .. tab.name)
	local re = {id=123}
	return re
end

C++

cpp 复制代码
#include <iostream>
extern "C"
{
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#include <vector>
#include <string>
#include <map>


int CTest(lua_State* L) // 返回值是固定的int类型,返回0表示没有返回参数,返回1表示有一个返回参数
{
	std::cout << "int CTest" << std::endl;
	return 0;
}

int CTestToString(lua_State* L)
{
	const char* luaStr = lua_tostring(L,1);
	std::cout << luaStr << std::endl;
	int num = lua_tointeger(L,2);
	std::cout << num << std::endl;
	bool is = lua_toboolean(L, 3);
	std::cout << is << std::endl;
	return 0;
}

int CTestArr(lua_State* L)
{
	std::vector<std::string> vStr;
	std::cout << "int CTestArr" << std::endl;
	int arraySize = luaL_len(L, 1); //获取表的大小
	for (int i = 1; i <= arraySize; ++i)
	{
		lua_pushnumber(L,i);	//往栈中压入一个数字,表示从数组中取那个下标的值,lua都是从1开始的所以i从1开始
		lua_gettable(L, 1);		//把上一行索引的位置出栈,再把i压入 栈
		vStr.push_back(lua_tostring(L,-1));
		lua_pop(L,1);
	}
	for (auto& value : vStr)
	{
		std::cout << value << std::endl;
	}
	return 0;
}

int CTestTable(lua_State* L)
{
	std::cout << "int CTestTable" << std::endl;
	/*   读取全部的表的内容 */
	std::map<std::string, std::string> mStr;
	lua_pushnil(L);
	while (lua_next(L, 1) != 0)
	{
		mStr[lua_tostring(L, -2)] = lua_tostring(L,-1);
		lua_pop(L,1);
	}
	for (auto& value : mStr)
	{
		std::cout << value.first << " = " << value.second << std::endl;
	}

	/* 只取一个
	lua_getfield(L,1,"name");
	std::cout << lua_tostring(L,-1) << std::endl;
	*/
	return 0;
}


int TestRe(lua_State* L)
{
	lua_pushstring(L,"return value");
	return 1;
}


int TestReTable(lua_State* L)
{
	lua_newtable(L);  // 创建一个表格,放在栈顶
	lua_pushstring(L,"name"); // 压入key
	lua_pushstring(L,"ccname");//压入value
	lua_settable(L,-3); //弹出key value,并设置到表,表在栈顶了作为返回值
	lua_pushstring(L, "age"); // 压入key
	lua_pushinteger(L, 21);//压入value
	lua_settable(L, -3); //弹出key value,并设置到表,表在栈顶了作为返回值
	return 1;
}

int main()
{
	lua_State *lua = luaL_newstate();
	luaopen_base(lua);
	luaopen_string(lua);
	lua_register(lua,"CTest",CTest); //第一个参数是lua状态指针,第二个参数是函数名称,第三个参数是lua函数指针,第二个参数和第三个参数可以用不同的名字,但第三个必须使用正确的函数指针
	lua_register(lua, "CTestToString", CTestToString);
	lua_register(lua, "CTestArr", CTestArr);
	lua_register(lua, "CTestTable", CTestTable);
	lua_register(lua, "TestRe", TestRe);
	lua_register(lua, "TestReTable", TestReTable);

	/*C++给lua传入普通值*/
	lua_pushstring(lua, "Hello");
	lua_setglobal(lua, "test");
	/*C++给lua传入普通表*/
	lua_newtable(lua);
	lua_pushstring(lua,"name");
	lua_pushstring(lua,"xiaoming");
	lua_settable(lua,-3);
	lua_pushstring(lua,"age");
	lua_pushinteger(lua,20);
	lua_settable(lua, -3);
	lua_setglobal(lua, "person");
	luaL_loadfile(lua, "D:\\code\\MyCode\\C++\\Lua\\CPPAddLua\\testLua\\x64\\Debug\\main.lua");
	lua_pcall(lua, 0,0,0);
	/*lua给C++传入普通值*/
	lua_getglobal(lua, "width");
	int width = lua_tointeger(lua,-1);
	lua_pop(lua,1);
	std::cout << width << std::endl;
	/*lua给C++传入表*/
	lua_getglobal(lua,"conf");
	lua_getfield(lua, -1, "titlename");
	std::cout << lua_tostring(lua,-1) << std::endl;
	lua_pop(lua, 1);
	lua_getfield(lua,-1,"height");
	std::cout << lua_tointeger(lua, -1) << std::endl;
	lua_pop(lua, 1);
	/*C++ 调用 Lua函数 */
	std::cout << "top is = " << lua_gettop(lua) << std::endl;
	int errfun = lua_gettop(lua);
	lua_getglobal(lua, "ferror");
	errfun++;
	lua_getglobal(lua, "event");
	lua_pushstring(lua,"key"); // 传入参数	
	
	lua_newtable(lua);
	lua_pushstring(lua,"name");
	lua_pushfstring(lua,"xiaoming");
	lua_settable(lua, -3);

	/*
	//第一个参数lua的状态,
	第二个参数是传递给 Lua 函数的参数数量,
	第三个参数 Lua 函数中返回的结果数量,
	第四个参数这是错误处理函数在堆栈中的索引。如果在调用 Lua 函数时发生了错误,Lua 将调用此错误处理函数。
	如果不需要错误处理函数,可以将其设置为 0。
	*/
	if (lua_pcall(lua, 2, 1, errfun) != 0)
	{	
		std::cout << "call event failed" << lua_tostring(lua, -1) << std::endl;
		lua_pop(lua,1);
	}
	else
	{
		lua_getfield(lua, -1,"id");
		std::cout << "lua return tab= " << lua_tointeger(lua, -1) << std::endl;
		lua_pop(lua, 1);
	}
	lua_pop(lua, 2);
	std::cout << "top is = " << lua_gettop(lua) << std::endl;



	lua_close(lua);
	getchar();
	return 0;
}
相关推荐
yezipi耶不耶4 分钟前
Rust入门之高级Trait
开发语言·后端·rust
双叶83617 分钟前
(C语言)超市管理系统 (正式版)(指针)(数据结构)(清屏操作)(文件读写)
c语言·开发语言·数据结构·c++·windows
为美好的生活献上中指23 分钟前
java每日精进 5.14【参数校验】
java·开发语言·spring boot·tomcat
末央&42 分钟前
【数据结构】手撕AVL树(万字详解)
数据结构·c++
序属秋秋秋43 分钟前
《数据结构初阶》【二叉树 精选9道OJ练习】
c语言·数据结构·c++·算法·leetcode
后青春期的诗go1 小时前
基于Rust语言的Rocket框架和Sqlx库开发WebAPI项目记录(一)
开发语言·后端·rust
景天科技苑2 小时前
【Rust闭包】rust语言闭包函数原理用法汇总与应用实战
开发语言·后端·rust·闭包·闭包函数·rust闭包·rust闭包用法
uyeonashi3 小时前
【Boost搜索引擎】构建Boost站内搜索引擎实践
开发语言·c++·搜索引擎
再睡一夏就好3 小时前
从硬件角度理解“Linux下一切皆文件“,详解用户级缓冲区
linux·服务器·c语言·开发语言·学习笔记
TIF星空4 小时前
【使用 C# 获取 USB 设备信息及进行通信】
开发语言·经验分享·笔记·学习·microsoft·c#