lua调用C++函数

第一步搭建lua的环境.

win10 lua环境搭建-CSDN博客

我使用的环境是win10+vs2015+lua54

先来个最简单的lua调用C++函数,

无参数无返回值的

第一步:定义C++函数.

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

这个函数,除了函数名可以自己定义其他的都要按这个来定义.

返回值是固定的int类型,返回0表示没有返回参数,返回1表示有一个返回参数.

第二步:注册函数.

cpp 复制代码
lua_register(lua,"CTest",CTest); 

第一个参数是lua的lua_State的指针,第二个是lua的注册函数名字,这个名字是在lua代码里使用的,第三个参数是函数指针就是刚才定义的C++函数.

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

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

int main()
{
	lua_State *lua = luaL_newstate();
	luaopen_base(lua);
	luaopen_string(lua);
	lua_register(lua,"CTest",CTest); //第一个参数是lua状态指针,第二个参数是函数名称,第三个参数是lua函数指针,第二个参数和第三个参数可以用不同的名字,但第三个必须使用正确的函数指针
	luaL_loadfile(lua, "D:\\code\\MyCode\\C++\\Lua\\CPPAddLua\\testLua\\x64\\Debug\\main.lua");
	lua_pcall(lua, 0,0,0);
	getchar();
	return 0;
}

直接运行

这样就是lua调用到了C++函数.当然这里lua调用C++ 函数是指在C++代码中的调用.

lua传递参数,没有返回值

只需要从lua的堆栈拿出一个参数即可.在此之前还需要再注册一下.

cpp 复制代码
lua_register(lua, "CTestToString", CTestToString);
cpp 复制代码
const char* luaStr = lua_tostring(L,1);

这样得到的就是lua传递的参数.

cpp 复制代码
int CTestToString(lua_State* L)
{
	const char* luaStr = lua_tostring(L,1);
	std::cout << luaStr << std::endl;
	return 0;
}

传第二个参数就再获取一下第二个参数.

cpp 复制代码
int num = lua_tointeger(L,2);
cpp 复制代码
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;
	return 0;
}

传递普通参数就这样传递.

lua传递数组给C++函数

第一步注册函数:

cpp 复制代码
lua_register(lua, "CTestArr", CTestArr);

第二步:编写接收函数

cpp 复制代码
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;
}

第三步:lua调用

.

lua传递表给C++函数

lua_next3(L,3)

  1. 先从栈顶弹出一个key
  2. 从栈指定位置的table里取下一对key-value,先将key入栈再将value入栈
  3. 如果第2步成功则返回非0值,否则返回0,并且不向栈中压入任何值.

第一步注册函数:

cpp 复制代码
lua_register(lua, "CTestTable", CTestTable);

第二步:

cpp 复制代码
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;
	}
	return 0;
}

第三步lua调用:

结果:

lua调用C++ 获取表中的内容

cpp 复制代码
	lua_getfield(L,1,"name");
	std::cout << lua_tostring(L,-1) << std::endl;

Lua调用C++参数类型检查

cpp 复制代码
	luaL_checktype(L,1,LUA_TBOOLEAN);


	if (lua_type(L, 1) != LUA_TBOOLEAN)
	{
		luaL_argerror(L,1,"bad argument");
	}

第一行,一旦不匹配代码就不会往下执行,

第二行的不匹配还会往下执行.

Lua调用C++ 返回值普通类型

第一步:注册函数:

cpp 复制代码
lua_register(lua, "TestRe", TestRe);

第二步写函数:

cpp 复制代码
int TestRe(lua_State* L)
{
	lua_pushstring(L,"return value");
	return 1;
}

一个返回参数就返回1,两个就返回2

第三步lua代码

结果:

lua返回表

第一步注册函数:

cpp 复制代码
lua_register(lua, "TestReTable", TestReTable);

第二步写注册函数

cpp 复制代码
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;
}

第三步:lua

结果:

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);
	luaL_loadfile(lua, "D:\\code\\MyCode\\C++\\Lua\\CPPAddLua\\testLua\\x64\\Debug\\main.lua");
	lua_pcall(lua, 0,0,0);
	getchar();
	return 0;
}

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"])
相关推荐
菜鸟~noob23326 分钟前
【Bonjour】华为Peerium架构深度解析:从冯·诺依曼到百万处理器“一台计算机”,附MATLAB性能仿真【含matlab代码,可直接运行】
开发语言·matlab·华为·peerium
朝朝辞暮i28 分钟前
C++第 2 课
c++
代码中介商34 分钟前
C++ 预约系统实战(三):服务端实现——libevent 事件驱动与业务路由
c++·json·c/s
白远山1 小时前
24小时自助健身房系统开发实战:从需求分析到完整指南
java·开发语言·数据库·数据挖掘·需求分析
布莱克6052 小时前
C++中的内存分区详解
c++
All for pursuit.2 小时前
【链表-9】146.LRU缓存
数据结构·c++·算法·leetcode
shmily麻瓜小菜鸡3 小时前
TDD(测试驱动开发)详解
开发语言·javascript·typescript·node.js·ecmascript
三克的油3 小时前
java-学习1
java·开发语言·学习
j7~3 小时前
【C++微服务项目开发脚手架】(接口篇一)gflags + gtest + spdlog 接口学习笔记
c++·学习·gtest·项目开发·spdlog·gflags·c++项目微服务开发脚手架
星期八不上发条3 小时前
智能指针是什么?使用场景,循环引用解决办法,面试回答
开发语言·c++·stl