lua调用C++函数

news2024/9/25 9:34:49

第一步搭建lua的环境.

win10 lua环境搭建-CSDN博客

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

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

无参数无返回值的

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

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

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

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

第二步:注册函数.

lua_register(lua,"CTest",CTest); 

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

#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的堆栈拿出一个参数即可.在此之前还需要再注册一下.

lua_register(lua, "CTestToString", CTestToString);
const char* luaStr = lua_tostring(L,1);

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

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

 

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

 

int num = lua_tointeger(L,2);
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++函数

第一步注册函数:

lua_register(lua, "CTestArr", CTestArr);

第二步:编写接收函数

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,并且不向栈中压入任何值.

第一步注册函数:

lua_register(lua, "CTestTable", CTestTable);

第二步:

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++ 获取表中的内容

	lua_getfield(L,1,"name");
	std::cout << lua_tostring(L,-1) << std::endl;

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

	luaL_checktype(L,1,LUA_TBOOLEAN);


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

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

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

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

第一步:注册函数:

lua_register(lua, "TestRe", TestRe);

第二步写函数:

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

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

第三步lua代码

结果:

lua返回表

第一步注册函数:

lua_register(lua, "TestReTable", TestReTable);

第二步写注册函数

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++全部代码:

#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全部代码:

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"])

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1486752.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是支持向量机(Support vector machine)和其原理

作为机器学习的基础算法&#xff0c;SVM被反复提及&#xff0c;西瓜书、wiki都能查到详细介绍&#xff0c;但是总是觉得还差那么点&#xff0c;于是决定自己总结一下。 一、什么是SVM&#xff1f; 1、解决什么问题&#xff1f; SVM&#xff0c;最原始的版本是用于最简单的线…

【C++从0到王者】第五十站:B树

文章目录 一、内查找与外查找1.内查找2.外查找 二、B树概念三、B树的插入1.B树的插入分析2.B树插入总结3.插入代码实现4.B树满树和最空时候的对比5.B树的删除6.遍历B树7.B树的性能分析 一、内查找与外查找 1.内查找 像我们之前所用的在内存中的查找就是内查找 种类数据格式时…

Arduino应用开发——使用GUI-Guider制作LVGL UI并导入ESP32运行

Arduino应用开发——使用GUI-Guider制作LVGL UI并导入ESP32运行 目录 Arduino应用开发——使用GUI-Guider制作LVGL UI并导入ESP32运行前言1 使用GUI-Guider设计UI1.1 创建工程1.2 设计UI 2 ESP工程导入UI2.1 移植LVGL2.2 移植UI文件2.3 调用UI文件2.4 烧录测试 结束语 前言 GU…

STM32(5) GPIO(2)输出

1.点亮LED 1.1 推挽接法和开漏接法 要想点亮LED&#xff0c;有两种接法 推挽接法&#xff1a; 向寄存器写1&#xff0c;引脚输出高电平&#xff0c;LED点亮&#xff1b;向寄存器写0&#xff0c;引脚输出低电平&#xff0c;LED熄灭。 开漏接法&#xff1a; 向寄存器写0&…

杂记-买华强北电子产品的教训

之前不信邪&#xff0c;去华强北买了一个西部数据所谓全新的机械硬盘&#xff0c;1T&#xff0c;差不多300元。用了不到一年就坏了。然后去官网查S/N&#xff0c;结果查无device。Onedrive同步的时候&#xff0c;我把同步路径设置为机械硬盘&#xff0c;结果机械硬盘崩的时候&a…

HarmonyOS Next 实现登录注册页面(ARKTS) 并使用Springboot作为后端提供接口

1. HarmonyOS next ArkTS ArkTS围绕应用开发在 TypeScript &#xff08;简称TS&#xff09;生态基础上做了进一步扩展&#xff0c;继承了TS的所有特性&#xff0c;是TS的超集 ArkTS在TS的基础上扩展了struct和很多的装饰器以达到描述UI和状态管理的目的 以下代码是一个基于…

【和鲸冬令营】通过数据打造爆款社交APP用户行为分析报告

【&#x1f40b;和鲸冬令营】通过数据打造爆款社交APP用户行为分析报告 文章目录 【&#x1f40b;和鲸冬令营】通过数据打造爆款社交APP用户行为分析报告1 业务背景2 数据说明3 数据探索性分析4 用户行为分析4.1 用户属性与行为关系分析4.2 转化行为在不同用户属性群体中的分布…

Android之MQTT的使用

MQTT的简单介绍 MQTT是广泛应用于物联网的传输协议&#xff0c;基于TCP MQTT有一个代理服务器&#xff0c;其客户端可以订阅主题或向一个主题发送消息&#xff0c;从而实现通信 MQTT 设计了 3 个 QoS 等级。 QoS 0&#xff1a;消息最多传递一次&#xff0c;如果当时客户端不…

Jmeter基础使用---Token鉴权接口关联

接口测试流程&#xff1a; 查看API接口文档&#xff0c;熟悉接口业务&#xff08;地址、端口、参数、鉴权、状态码&#xff09;设计接口测试用例&#xff08;正例&#xff1a;正确的结果&#xff1b;反例&#xff1a;鉴权异常、参数异常、兼容异常、其他异常&#xff09;使用接…

Java中的List

List集合的特有方法 方法介绍 方法名描述void add(int index,E element)在此集合中的指定位置插入指定的元素E remove(int index)删除指定索引处的元素&#xff0c;返回被删除的元素E set(int index,E element)修改指定索引处的元素&#xff0c;返回被修改的元素E get(int inde…

rtt的io设备框架面向对象学习-io设备管理层

目录 1.设备基类2.rtt基类2.1 rtt基类定义2.2 对象容器定义2.3 rtt基类构造函数 3.io设备管理接口4.总结 这层我的理解就是rtt基类和设备基类所在&#xff0c;所以抽离出来好点&#xff0c;不然每个设备类都要重复它。 1.设备基类 /include/rtdef.h中定义了设备基类struct rt_…

Spring:EnclosingClass工具类分辨

Spring&#xff1a;EnclosingClass工具类分辨 1 前言 通过Spring的工具分辨EnclosingClass类。 测试类如下&#xff1a; package com.xiaoxu.test.enclosingClass;/*** author xiaoxu* date 2024-01-18* java_demo2:com.xiaoxu.test.enclosingClass.Outter*/ public class …

计算机专业必看的几部电影推荐

计算机专业必看的几部电影&#xff0c;就像一场精彩的编程盛宴&#xff01;《黑客帝国》让你穿越虚拟世界&#xff0c;感受高科技的魅力&#xff1b;《社交网络》揭示了互联网巨头的创业之路&#xff0c;《源代码》带你穿越时间解救世界&#xff0c;这些电影不仅带我们穿越到科…

模型部署 - onnx 的导出和分析 -(1) - PyTorch 导出 ONNX - 学习记录

onnx 的导出和分析 一、PyTorch 导出 ONNX 的方法1.1、一个简单的例子 -- 将线性模型转成 onnx1.2、导出多个输出头的模型1.3、导出含有动态维度的模型 二、pytorch 导出 onnx 不成功的时候如何解决2.1、修改 opset 的版本2.2、替换 pytorch 中的算子组合2.3、在 pytorch 登记&…

SpringBoot+Maven多环境配置模式

我这里有两个配置文件 然后在最外层的父级POM文件里面把这个两个配置文件写上 <profiles><profile><id>druid</id><properties><spring.profiles.active>druid</spring.profiles.active></properties><activation><…

管理系统提升:列表页构成要素,拒绝千篇一律

大家伙&#xff0c;我是大千UI工场&#xff0c;专注UI知识案例分享和接单&#xff0c;本期带来B端系统列表页的分享&#xff0c;欢迎大家关注、互动交流。 一、什么是列表页 管理系统列表页是指管理系统中用于展示和管理数据的页面&#xff0c;通常以表格或列表的形式呈现。列…

经典语义分割(一)利用pytorch复现全卷积神经网络FCN

经典语义分割(一)利用pytorch复现全卷积神经网络FCN 这里选择B站up主[霹雳吧啦Wz]根据pytorch官方torchvision模块中实现的FCN源码。 Github连接&#xff1a;FCN源码 1 FCN模型搭建 1.1 FCN网络图 pytorch官方实现的FCN网络图&#xff0c;如下所示。 1.2 backbone FCN原…

斐波那契数列模型---使用最小花费爬楼梯

746. 使用最小花费爬楼梯 - 力扣&#xff08;LeetCode&#xff09; 1、状态表示&#xff1a; 题目意思即&#xff1a;cost[i]代表从第i层向上爬1阶或者2阶&#xff0c;需要花费多少力气。如cost[0]&#xff0c;代表从第0阶爬到第1阶或者第2阶需要cost[0]的力气。 一共有cost.…

Java - List集合与Array数组的相互转换

一、List 转 Array 使用集合转数组的方法&#xff0c;必须使用集合的 toArray(T[] array)&#xff0c;传入的是类型完全一样的数组&#xff0c;大小就是 list.size() public static void main(String[] args) throws Exception {List<String> list new ArrayList<S…

梯度下降算法(带你 原理 实践)

目录 一、引言 二、梯度下降算法的原理 三、梯度下降算法的实现 四、梯度下降算法的优缺点 优点&#xff1a; 缺点&#xff1a; 五、梯度下降算法的改进策略 1 随机梯度下降&#xff08;Stochastic Gradient Descent, SGD&#xff09; 2 批量梯度下降&#xff08;Batch…