lua调用C/C++的函数,十分钟快速掌握
系列文章目录
lua调用C\C++动态库函数
- 系列文章目录
- 摘要
- 环境
- 使用步骤
- 你需要有个lua环境
- 引入库
- 码代码
- lua代码
摘要
在现代软件开发中,Lua作为一种轻量级脚本语言,在游戏开发、嵌入式系统等领域广泛应用。Lua与C/C++的高度集成使得开发者能够借助其灵活性和高效性实现更强大的功能。本文将通过一些简单、直接的示例探讨Lua调用C/C++函数的技术。Lua通过调用C/C++实现的extern "C"函数来交互,首先,我们需要在C/C++中编写适当的包装函数,并使用Lua API将其注册到Lua虚拟机中,这一过程包括参数的传递、函数调用以及返回值的处理。通过合理设计的接口,生成动态库文件使其在lua脚本中用require引用,我们能够在Lua中直接调用C/C++函数,实现跨语言的功能扩展。这为项目提供了更大的灵活性,允许开发者在Lua中编写高层逻辑,同时利用C/C++的性能优势处理底层任务。从实践角度看,Lua调用C/C++的技术架构在提高代码可维护性和性能的同时,也为项目带来了更强大的扩展性。通过深入学习Lua与C/C++交互的原理和最佳实践,开发者可以更好地应用这一技术,提升项目的开发效率和整体性能。
还有一种提供C API给lua用的方法:把lua的源码clone一份自己改,定义一个library导出,然后编译成可执行文件或者库,那么lua依然可以通过require引入和使用。
提示:以下是本篇文章正文内容,下面案例可供参考
环境
软件 | 版本 |
---|---|
Windows | 10 |
visual studio | 2022 |
lua | 5.1 |
C++ | 17 |
使用步骤
你需要有个lua环境
在lua官网下载编译好的动态库、静态库、头文件和可执行二进制文件。
https://luabinaries.sourceforge.net/
拿到lua.hpp头文件和lua5.1.lib静态库,加到自己项目的引用。
引入库
lua.hpp头文件去安装目录找。
码代码
头文件
代码如下(示例):
#pragma once
/*
几个简单的函数
*/// step 1
#include "lua.hpp"// step 2 定义自己的函数
int addTwoNumber(int a, int b)
{return a + b;
}const char* linkNameAndNumber(const char* name, int age)
{std::unique_ptr<char> pbuf(new char[128]);sprintf(pbuf.get(), "Your name is %s, and %d years old.", name, age);std::string r(pbuf.get());std::cout<<"C source output " << r << std::endl;auto rbuf = new char[128];memcpy(rbuf, pbuf.get(), sizeof(pbuf.get()));std::cout << rbuf << " buffer content" << std::endl;return rbuf;
}const wchar_t* wLinkNameAndNumber(const wchar_t* name, int age)
{std::unique_ptr<wchar_t> pbuf(new wchar_t[128]);wsprintf(pbuf.get(), L"Your name is %s, and %d years old.", name, age);std::wstring r(pbuf.get());std::wcout << L"C source output " << r << std::endl;return r.c_str();
}/*** step 3 定义函数的wrapper* \brief origin function* \param L* \return*/
extern "C" int addTwoNumberWrapper(lua_State * L)
{double a, b, sum = 0;int pCount = lua_gettop(L);for (int i = 0; i <= pCount; ++i){if (i == 1){a = lua_tonumber(L, i);}else if (i == 2){b = lua_tonumber(L, i);}}sum = addTwoNumber(a, b);lua_pushnumber(L, sum);return 1;
}extern "C" int linkNameAndNumberWrapper(lua_State * L)
{int pCount = lua_gettop(L);const char* name = lua_tostring(L, 1);int age = lua_tointeger(L, 2);auto result = linkNameAndNumber(name, age);lua_pushstring(L, result);return 1;
}
dllmain.cpp
/*** step 4 定义函数的wrapper注册表* \brief function registry table*/
static luaL_Reg cMethods[] = {{"addTwoNumber", addTwoNumberWrapper},{"linkNameAndNumber", linkNameAndNumberWrapper},{NULL, NULL}
};/*step 5 创建lua_openlibrary函数
*/
extern "C" __declspec(dllexport)
int luaopen_MyMethodLib(lua_State * L)
{std::cout << "=========载入MyMethodLib库======" << std::endl;const char* libName = "MyMethodLib";luaL_register(L, libName, cMethods);return 1;
}
Windows平台生成的动态库可以使用visual studio命令行工具的dumpbin /exports 查看导出符号表,检查函数导出情况。
生成的动态库放到lua安装目录下或者自己的lua脚本目录下。
lua代码
local myMethodLib = require("MyMethodLib")local r1 = myMethodLib.addTwoNumber(1,2)
local r2 = myMethodLib.linkNameAndNumber("Michael",67)print(r1, r2)
使用lua.exe运行脚本即可。
相关文章:
lua调用C/C++的函数,十分钟快速掌握
系列文章目录 lua调用C\C动态库函数 系列文章目录摘要环境使用步骤你需要有个lua环境引入库码代码lua代码 摘要 在现代软件开发中,Lua作为一种轻量级脚本语言,在游戏开发、嵌入式系统等领域广泛应用。Lua与C/C的高度集成使得开发者能够借助其灵活性和高…...

自定义GPT已经出现,并将影响人工智能的一切,做好被挑战的准备了吗?
原创 | 文 BFT机器人 OpenAI凭借最新突破:定制GPT站在创新的最前沿。预示着个性化数字协助的新时代到来,ChatGPT以前所未有的精度来满足个人需求和专业需求。 从本质上讲,自定义GPT是之前的ChatGPT的高度专业化版本或代理,但自定…...

vue中一个页面引入多个相同组件重复请求的问题?
⚠️!!!此内容需要了解一下内容!!! 1、会使用promise??? 2、 promise跟 async 的区别??? async 会终止后面的执行,后续…...

Uniapp连接iBeacon设备——实现无线定位与互动体验(实现篇)
export default { data() { return { iBeaconDevices: [], // 存储搜索到的iBeacon设备 deviceId: [], data: [], url: getApp().globalData.url, innerAudioContext: n…...
【ceph】ceph集群删除pool报错: “EPERM: pool deletion is disabled“
本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》:python零基础入门学习 《python运维脚本》: python运维脚本实践 《shell》:shell学习 《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战 《k8…...
【微信小程序】使用npm包
1、小程序对npm的支持与限制2、Vant Weapp通过 npm 安装修改 app.json修改 project.config.json构建 npm 包 3、使用4、定制全局主题样式5、API Promise化 1、小程序对npm的支持与限制 目前,小程序中已经支持使用npm安装第三方包, 从而来提高小程序的开发…...
【开发记录篇】第二篇:SQL创建分区表
实现分区表注意事项 分区字段必须在主键中存在 使用时间分区时,字段类型不支持 timestamp,需改为 datetime 年分区示例 下表中使用 insert_time 时间进行分区 CREATE TABLE t_log (id bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 日志ID,inse…...
vue 使用 this.$router.push 传参数,接参数的 query或params 两种方法示例
背景:vue项目 使用this.$router.push进行路由跳转时,可以通过query或params参数传递和接收参数。 通过query参数传递参数: // 传递参数 this.$router.push({path: /target,query: {id: 1,name: John} }); // 接收参数 this.$route.query.id …...

rk3588 usb网络共享连接
出门在外总会遇到傻 X 地方 没有能连接公网的 网口给香橙派连网 而我的香橙派5plus 没有wifi模块。。。话不多说 在手机上看一眼手机的mac地址, 在rk3588 上执行以下命令: sudo ifconfig usb0 down sudo ifconfig usb0 hw ether 58:F2:FC:5D:D4:7A //该m…...
shell 拒绝恶意连接脚本 centos7.x拒绝恶意连接脚本
1. crontab -l 脚本频率: */2 * * * * /bin/bash /home/shell/deny.sh 2. 脚本: rm -rf /home/shell/ip_list cat /var/log/secure | grep "Failed password for" | awk {print$(NF-3)} | sort | uniq -c > /home/shell/ip_list #cat /va…...
【系统架构设计】计算机公共基础知识: 2 计算机系统基础知识
目录 一 计算机系统组成 二 操作系统 三 文件系统 四 系统性能 一 计算机系统组成...

什么是代理模式,用 Python 如何实现 Proxy(代理 或 Surrogate)对象结构型模式?
什么是代理模式? 代理(Proxy)是一种结构型设计模式,其目的是通过引入一个代理对象来控制对另一个对象的访问。代理对象充当目标对象的接口,这样客户端就可以通过代理对象间接地访问目标对象,从而在访问过程…...

国内领先的五大API接口供应商
API(Application Programming Interface)接口,现在很多应用系统中常用的开放接口,对接相应的系统、软件功能,简化专业化的程序开发。作者用过的国内比较稳定的API接口供应商有如下几家,大家可以参考选择&am…...

第十九章 Java绘图
一,Java绘图类 19.1.1Graphics类 Graphics类是所有图形上下文的抽象基类,它允许应用程序在组件以及闭屏图像上进行绘制。 可实现直线,矩形,多边形,椭圆,圆弧等形状和文本,图片的绘制制作。 …...

【C++面向对象】13. 接口 / 抽象类*
文章目录 【 1. 抽象类 】1.1 抽象类的定义1.2 抽象类的应用条件1.3 实例 【 2. 设计策略 】 接口描述了类的行为和功能,而不需要完成类的特定实现。C 接口是使用 抽象类(abstract base class,也称为ABC) 来实现的。 【 1. 抽象类…...

LeetCode热题100——二分查找
二分查找 1. 搜索插入位置2. 搜素二维矩阵3. 在排序数组中查找第一个和最后一个元素位置 1. 搜索插入位置 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 // 题…...

使用VC++实现分段线性变换,直方图均衡化、锐化处理(使用拉普拉斯算子)
图像锐化1 实验要求 5.1实验目的、要求 实验目的: (1)掌握图像增强的原理与相关方法。 (2)能使用VC实现图像增强的一些相关功能。 实验要求: A部分: (1)对一幅256级灰度…...
react class改hooks写法
类头修改 export default class EditUseTable extends Component 改为 export default function EditUseTable({})参数修改 constructor(props) {super(props)const {dbRecord, type, currentRecord, readOnly, updateTaxAmount} this.props改为(主函数的参数&a…...

桂院校园导航 | 云上高校导航 云开发项目 二次开发教程 1.3
Gitee代码仓库:桂院校园导航小程序 GitHub代码仓库:GLU-Campus-Guide 演示视频 中国大学生计算机设计大赛-移动应用与开发-云上高校导航 升级日志 1.3 优化了小程序的数据存储方式,对部分页面进行了调整,调整了功能和代码。 引…...

sscanf提取相应字符到数组
代码如下 #include<stdio.h> #include<string.h>int main(int argc, char const *argv[]) {char buf[128] {0};int m1 0, m2 0;int s1 0, s2 0;char lrc[128] "";sscanf("[02:16.33][04:11.44]我想大声宣布对你恋恋不舍","[%*1d%d…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...

恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...
Linux安全加固:从攻防视角构建系统免疫
Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...

【1】跨越技术栈鸿沟:字节跳动开源TRAE AI编程IDE的实战体验
2024年初,人工智能编程工具领域发生了一次静默的变革。当字节跳动宣布退出其TRAE项目(一款融合大型语言模型能力的云端AI编程IDE)时,技术社区曾短暂叹息。然而这一退场并非终点——通过开源社区的接力,TRAE在WayToAGI等…...