C++与lua联合编程

news2024/9/20 5:57:45

C++与lua联合编程

  • 一、环境配置
  • 二、lua基本语法
    • 1.第一个lua和C++程序
    • 2.基本数据类型和变量
      • 2.1 Nil
      • 2.2 Booleans
      • 2.3 Numbers
      • 2.4 String(最常用)
    • 3. 字符串处理
      • 3.1 错误处理
      • 3.2 字符串长度:string.len
      • 3.3 字符串子串 :string.sub
      • 3.4 字符串查找: string.find
      • 3.5字符串替换: string.gsub
    • 4.控制结构语句
      • 4.1 if条件语句
      • 4.2 while 循环语句
      • 4.3 repeat循环语句
      • 4.4 for循环语句
    • 5.表和函数
      • 5.1表的大小
      • 5.2 插入元素
      • 5.3 删除元素
      • 5.4 二维数组
      • 5.5 函数
        • 普通参数
        • 可变参数
        • 返回值
        • 使用变量定义函数
  • 三、Lua调用C++
    • 1.原理
    • 2.传递参数类型
      • 2.1 传递普通参数
      • 2.2 传递数组参数
      • 2.3 传递表
      • 2.4 参数类型检查
    • 3.获取返回值类型
  • 四、C++调用Lua
    • 1.C++给Lua传递变量并访问Lua的全局变量
    • 2.C++给Lua传递表并访问Lua的表
    • 3.C++调用Lua的函数
    • 4.错误显示和堆栈清理
    • 5.C++调用Lua的函数并传递参数
    • 6.C++调用Lua函数并获取返回的表
      • 2.3 传递表
      • 2.4 参数类型检查
    • 3.获取返回值类型
  • 四、C++调用Lua
    • 1.C++给Lua传递变量并访问Lua的全局变量
    • 2.C++给Lua传递表并访问Lua的表
    • 3.C++调用Lua的函数
    • 4.错误显示和堆栈清理
    • 5.C++调用Lua的函数并传递参数
    • 6.C++调用Lua函数并获取返回的表
  • 五、Lua和MFC结合开发

一、环境配置

首先下载lua源码。

image-20240717211614791

将main函数改名后编译。

image-20240717211633975

目前我的工作目录是工程文件所在目录,src存放了lua的源码。

image-20240717212024743

修改dll输出路径。

image-20240717212140234

image-20240717213055702

指定导出宏生成.lib文件

生成 .lib 文件需要导出宏,这是为了确保在编译和链接过程中正确处理导入和导出的符号。具体来说,导出宏(export macro)用于标记哪些函数、变量或类应当从 DLL 中导出,使其可以在 DLL 外部被访问。

image-20240717213027504

image-20240717213302949

修改lib的输出路径。

image-20240717212303620

image-20240717213109132

二、lua基本语法

1.第一个lua和C++程序

image-20240717214858982

image-20240717215134442

ben

2.基本数据类型和变量

  • 全局变量

类型+变量名

image-20240717215941778

image-20240717215952423

image-20240717220005543

  • 本地变量(尽量用本地变量,保证及时的垃圾回收)

image-20240717220025102

image-20240717220104052

Lua基本数据类型:

2.1 Nil

在 Lua 中,nil 是一种特殊的数据类型,用于表示“无值”或“空值”。它的主要用途有以下几个方面:

  1. 表示变量没有值nil 用于区分变量是否有值。例如,如果一个变量被赋值为 nil,这意味着该变量目前没有任何值。
  2. 删除表中的元素:在 Lua 中,将表(table)中的元素赋值为 nil,可以删除该元素。
  3. 全局变量和垃圾回收:将全局变量设置为 nil 可以将其标记为可回收,从而允许垃圾回收器释放相关的内存。
local a = nil
print(type(a))  -- 输出:nil

这段代码展示了如何将一个局部变量 a 设为 nil,然后通过 type 函数检查其类型。type(a) 会返回 nil,表示变量 a 目前没有值。

2.2 Booleans

在 Lua 中,boolean 类型有两个值:truefalse。它们通常用于条件判断和控制流(如 if 语句、循环等)。

在 Lua 中,只有 falsenil 会被视为假(false),其他所有值,包括数值 0,都被视为真(true)。这与一些其他编程语言(如 C/C++)中的行为不同,在那些语言中,0 通常被视为假。

2.3 Numbers

  1. Lua 中没有整数,都是用浮点数运算

    在 Lua 5.3 之前,Lua 语言只使用浮点数来表示所有的数字,这意味着即使你写的是一个整数,内部也是用浮点数来存储和运算的。这种浮点数对应于 C 语言中的 double 类型。

  2. 新版 Lua 中有基于 64 位的整型

    从 Lua 5.3 开始,Lua 引入了整数类型(integer),这是一个 64 位的整数。这一变化使得 Lua 可以更高效地处理整数运算,同时也保留了对浮点数的支持。现在,Lua 支持两种数字类型:整数和浮点数。

  3. tonumber 转换格式

    tonumber 是 Lua 内置的一个函数,用于将字符串或其他类型的值转换为数字。这个函数在需要将其他数据类型转换为数字时非常有用。

image-20240717221752481

image-20240717221811534

2.4 String(最常用)

1.tostring 转换格式:tostring 函数可以将其他数据类型转换为字符串。

image-20240720123124555

2.多行字符串赋值:使用 [[]] 可以定义多行字符串,这在需要处理大段文本时非常有用。

image-20240720123258928

3.转义字符:Lua 中的字符串可以使用与 C 语言相同的转义字符。例如,\n 表示换行,\" 表示双引号。

image-20240720123417090

4.字符串拼接:Lua 使用 .. 运算符进行字符串拼接。

image-20240720123654579

3. 字符串处理

在Lua中,字符串处理是一个非常常见的任务,Lua提供了一些内置函数来处理字符串。

3.1 错误处理

image-20240720124238631

3.2 字符串长度:string.len

string.len 函数用于获取字符串的长度。

image-20240720124523504

image-20240720124728580

加载string库

在 Lua 5.2 及以后的版本中,luaL_openlibs 函数会自动打开所有标准库。

image-20240720130810760

3.3 字符串子串 :string.sub

string.sub 函数用于从字符串中提取子串。参数包括字符串、起始位置和结束位置。

image-20240720131817404

3.4 字符串查找: string.find

string.find 函数用于在字符串中查找子串,返回子串的起始和结束位置。它支持正则表达式。

image-20240720131656977

3.5字符串替换: string.gsub

string.gsub 函数用于在字符串中替换子串。它支持正则表达式。

image-20240720131933396

4.控制结构语句

4.1 if条件语句

条件语句结构:

if 条件 then
    -- then-part
elseif 其他条件 then
    -- elseif-part
else
    -- else-part
end

在条件语句中,可以使用逻辑操作符来构建更复杂的条件表达式。常见的逻辑操作符包括:

  • < :小于
  • > :大于
  • <= :小于等于
  • >= :大于等于
  • ~= :不等于
  • == :等于

image-20240720222905809

image-20240720222928486

4.2 while 循环语句

while 循环语句用于在条件为真时重复执行某段代码。当条件变为假时,循环结束。while 循环的基本结构如下:

while 条件 do
    -- 循环体
end

在循环中,可以使用 break 语句提前退出循环。

在 Lua 中,not 操作符用于取反一个条件表达式。在使用 not 操作符时,注意加上括号以确保逻辑的正确性。

image-20240720230007415

4.3 repeat循环语句

repeat...until 循环类似于 while 循环,但它至少会执行一次循环体,然后再检查条件是否为真。如果条件为假,循环体会继续执行,直到条件为真时退出循环

repeat
    -- 循环体
until 条件

image-20240720230458003

image-20240720230633261

4.4 for循环语句

Lua 提供了两种类型的 for 循环:数值循环和泛型循环。

数值循环用于遍历一段数值范围,具有固定的步长。

for var = from, to, step do
    -- 循环体
end

image-20240720230903497

image-20240720230933083

泛型循环用于遍历集合,如表(数组)或字典。Lua 提供了 pairsipairs 函数来支持泛型循环。

  • pairs 遍历表的所有键值对,适用于字典。

image-20240720232014144

image-20240720232219227

  • ipairs 以整数顺序遍历表的元素,适用于数组。

image-20240720231246550

5.表和函数

5.1表的大小

table.getn(t) 函数用于获取表 t 的大小,但在 Lua 5.1 之后的版本中,建议使用 # 操作符。

在 Lua 中,# 操作符(长度运算符)只能用于顺序整数键的表(即数组),而不能用于键为字符串或非连续整数的表(即字典)。

image-20240721004631723

image-20240721004710470

5.2 插入元素

table.insert(t, pos, value) 函数用于在表 t 中插入一个元素。如果没有指定 pos,则默认在表的末尾插入。

image-20240721005627015

字典的元素插入和删除

image-20240721005339310

5.3 删除元素

table.remove(t, [pos]) 函数用于从表 t 中删除一个元素。如果没有指定 pos,则默认删除表的最后一个元素。函数返回被删除的元素。

image-20240721005849522

5.4 二维数组

image-20240721011511994

5.5 函数

function func_name(arguments-list)
    -- statements-list
end

Lua 函数可以接受普通参数和可变参数。

普通参数

image-20240721011835977

可变参数

image-20240721012146775

image-20240721012305320

image-20240721012532723

返回值

image-20240721013146582

使用变量定义函数

image-20240721013333040

三、Lua调用C++

image-20240721013447292

image-20240721013535530

1.原理

Lua 调用 C++ 函数的基本原理是将 C++ 函数注册到 Lua 虚拟机中,使其可以在 Lua 脚本中像普通 Lua 函数一样调用。这涉及以下几个步骤:

  1. 定义C++函数:首先,我们定义一个C++函数,例如 addgreet。这些函数的参数类型都是 lua_State*,并且返回值类型是 int
  2. 获取参数:使用 lua_tonumberlua_tostring 等函数从Lua栈中获取参数。
  3. 执行逻辑:在C++函数中执行所需的逻辑操作。
  4. 返回结果:将结果压入Lua栈,并返回结果数量。
  5. 注册函数:使用 lua_register 将C++函数注册为Lua全局函数。
  6. 调用函数:在Lua脚本中,直接调用注册的C++函数

返回值数量:函数最后返回一个整数,表示压入Lua栈的返回值数量。

image-20240721015839563

image-20240721015814504

2.传递参数类型

Lua 和 C++ 之间可以传递多种类型的参数,包括数字、字符串、布尔值和用户自定义类型(如指针或结构体)。

  • lua_gettop(lua_State* L):返回堆栈中元素的数量,即传递给函数的参数数量。
  • lua_isnumber(lua_State* L, int index):检查堆栈中的值是否是数字。
  • lua_tonumber(lua_State* L, int index):将堆栈中的值转换为数字。
  • lua_isstring(lua_State* L, int index):检查堆栈中的值是否是字符串。
  • lua_tostring(lua_State* L, int index):将堆栈中的值转换为字符串。
  • lua_pushnumber(lua_State* L, lua_Number n):将一个数字压入堆栈。
  • lua_pushstring(lua_State* L, const char* s):将一个字符串压入堆栈。

在 Lua 中,参数的位置是从 1 开始索引的。第一个参数的位置是 1,第二个参数的位置是 2,以此类推。通过在 C++ 函数中使用 lua_tonumberlua_tostring 等函数,并传入相应的索引,可以获取相应的参数值。

2.1 传递普通参数

image-20240721021057165

image-20240721021105166

image-20240721021925453

2.2 传递数组参数

image-20240721013535530

image-20240721022450816

lua_gettable 使用栈顶的索引(即 i)从表中获取对应的值,并将该值压入栈顶。例如,如果 i1,获取数组中第一个元素,并将该元素压入栈顶。

image-20240721024335417

在Lua中,所有的操作都是通过堆栈完成的。当你希望从表中获取某个元素时,首先需要将该元素的索引(下标)压入堆栈。

lua_pushnumber(L, i);  // 将索引 i 压入栈顶

这行代码将当前的索引 i 压入堆栈。lua_pushnumber 函数将一个数字压入堆栈。

在将索引压入堆栈之后,使用 lua_gettable 函数来获取表中的值。lua_gettable 会使用栈顶的值作为索引,从给定位置的表中获取相应的值,并将该值压入栈顶。

lua_gettable(L, 1);  // 从索引为 1 的表中获取值(根据栈顶的索引 i)

在处理完当前元素后,需要将栈顶的值弹出,以便在下一次迭代时堆栈状态保持一致。

lua_pop(L, 1);  // 弹出栈顶的值

2.3 传递表

2.4 参数类型检查

3.获取返回值类型

C++ 函数可以返回各种类型的值给 Lua 脚本,包括数字、字符串、布尔值和结构体对象。Lua 脚本可以通过 Lua API 获取这些返回值并使用它们。

四、C++调用Lua

1.C++给Lua传递变量并访问Lua的全局变量

2.C++给Lua传递表并访问Lua的表

3.C++调用Lua的函数

4.错误显示和堆栈清理

5.C++调用Lua的函数并传递参数

6.C++调用Lua函数并获取返回的表

为 1 的表中获取值(根据栈顶的索引 i)

在处理完当前元素后,需要将栈顶的值弹出,以便在下一次迭代时堆栈状态保持一致。

lua_pop(L, 1);  // 弹出栈顶的值

2.3 传递表

2.4 参数类型检查

3.获取返回值类型

C++ 函数可以返回各种类型的值给 Lua 脚本,包括数字、字符串、布尔值和结构体对象。Lua 脚本可以通过 Lua API 获取这些返回值并使用它们。

四、C++调用Lua

1.C++给Lua传递变量并访问Lua的全局变量

2.C++给Lua传递表并访问Lua的表

3.C++调用Lua的函数

4.错误显示和堆栈清理

5.C++调用Lua的函数并传递参数

6.C++调用Lua函数并获取返回的表

五、Lua和MFC结合开发

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

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

相关文章

Evil-WinRM一键测试主机安全情况(KALI工具系列四十四)

目录 1、KALI LINUX 简介 2、Evil-WinRM 3、信息收集 3.1 目标IP 3.2 kali的IP 4、操作步骤 4.1 用户访问 4.2 使用哈希值 4.3 文件处理 5、总结 1、KALI LINUX 简介 Kali Linux 是一个功能强大、多才多艺的 Linux 发行版 &#xff0c;广泛用于网络安全社区。它具有全…

swiftui使用ScrollView实现左右滑动和上下滑动的效果,仿小红书页面

实现的效果如果所示&#xff0c;顶部的关注用户列表可以左右滑动&#xff0c;中间的内容区域是可以上下滚动的效果&#xff0c;点击顶部的toolbar也可以切换关注/发现/附近不同页面&#xff0c;实现翻页效果。 首页布局 这里使用了NavigationStack组件和tabViewStyle样式配置…

在项目服务器部署git 并实现自动提交

以下场景适合在服务器当中使用git 方便提交代码&#xff0c;同时不需要外部的git仓库&#xff08;码云gitee或者github作为管理平台&#xff09;。依靠服务器本身ssh 连接协议做为git提交的地址&#xff0c;同时利用钩子自动同步项目代码 首先下载git sudo apt update sudo a…

Linux最直观的性能分析(热点分析)-编译perf并生成火焰图

本文先介绍了linux下perf工具的使用场景&#xff0c;然后对命令行安装和源码编译安装两种方式做了说明&#xff0c;接下来通过最简单的perf top命令给出perf的直观印象&#xff0c;最后通过perf record生成火焰图的方式说明如何发现进程中的函数热点。 一、perf工具介绍 per…

00 JavaWeb

学习资料&#xff1a;B站视频-黑马程序员JavaWeb基础教程 文章目录 JavaWeb1、JavaWeb简介2、 JavaWeb主要内容3、JavaWeb技术栈4、JavaWeb课程安排5、Web核心课程安排 JavaWeb 1、JavaWeb简介 Web&#xff1a;全球广域网&#xff0c;也称为万维网(www)&#xff0c;能够通过浏…

C++: 链表回文结构/分割链表题解

目录 1.链表的回文结构 分析 代码 2.链表分割 ​编辑分析 代码 1.链表的回文结构 分析 这道题的难点是空间复杂度为O&#xff08;1&#xff09; 结合逆置链表找到链表的中间节点就可以解决了。 先找到链表的中间节点&#xff0c;再对中间节点的下一个节点进行逆置&…

macbook pro大模型推理

安装与配置 参考github ollama 链接安装ollama。安装完成后,安装常用的模型,下载速度超快。 性能测试 在进行实际测试之前,我首先对模型进行了预处理,以确保其在 M3 Max 上能够高效运行。测试过程中,我主要关注了以下几个方面: 模型加载时间 加载大型模型通常需要较…

Python WebUIAPI:打造交互式Web界面的利器

Python WebUIAPI&#xff1a;打造交互式Web界面的利器 引言&#xff1a;交互式Web界面的革新 在当今快速发展的互联网时代&#xff0c;Web界面的交互性已成为衡量用户体验的重要标准。Python作为一门流行的编程语言&#xff0c;其生态中涌现出许多强大的库来帮助开发者构建交互…

组队学习——贝叶斯分类器

前言 本次数据继续沿用上一次主题的【组队学习——支持向量机-CSDN博客】 数据处理部分延续【组队学习——支持向量机】主题的处理办法对应划分训练集和验证集 模型选择 本次贝叶斯分类器模型的较多&#xff0c;常用的为高斯朴素贝叶斯分类器、多项式朴素贝叶斯分类器、伯努…

2024年超好用的4款PDF阅读器推荐

PDF文件已经是我们平时常常会接触到的文件&#xff0c;但是无论是阅读和编辑都需要依赖一些工具&#xff0c;所以今天给大家介绍的是4个很多人都在使用的PDF阅读器。 &#xff11;、福昕PDF阅读软件 这款PDF编辑器是一个大厂其他的产品&#xff0c;功能非常的强大&#xff0c;…

Build a Large Language Model (From Scratch)GPT-4o翻译和代码每行中文注释Ch4

目录 4 Implementing a GPT model from Scratch To Generate TextThis chapter covers4.1 Coding an LLM architectureListing 4.1 A placeholder GPT model architecture class4.2 Normalizing activations with layer normalization4.3 Implementing a feed forward network …

STM32CUBEMX_SPI_驱动WS2811灯带

STM32CUBEMX_SPI_驱动WS2811灯带 前言&#xff1a; 关于这种带芯片的之前我都是使用GPIO模拟时序&#xff0c;但是带来一个很大的弊端&#xff0c;那就是严重占用CPU资源&#xff0c;使得其他代码逻辑没办法正常执行了&#xff0c;想办法搞一个单片机的外设使用DMA功能&#xf…

LeetCode-day21-1186. 删除一次得到子数组最大和

LeetCode-day21-1186. 删除一次得到子数组最大和 题目描述示例示例1&#xff1a;示例2&#xff1a;示例3&#xff1a; 思路代码 题目描述 给你一个整数数组&#xff0c;返回它的某个 非空 子数组&#xff08;连续元素&#xff09;在执行一次可选的删除操作后&#xff0c;所能得…

【学术研究、研究热点、最新前沿】如何跟踪最新的论文

1.跟踪arxiv 使用https://www.arxivdaily.com/接收每天的推送。 2.跟踪热点文章的引用 使用semantic scholar。 3.跟踪某个学术大佬或者主题 3.1 使用web of science。 3.2 使用文献鸟 4.跟踪某个期刊

pico+unity3d 射线交互教程

前期配置&#xff1a;环境配置参考教程一&#xff0c;手部模型参考教程二&#xff0c;场景基于上一篇搭建。 最终效果&#xff1a;手部射线&#xff08;初始不可见&#xff09;对准 UI 显示&#xff0c;按下手柄 Trigger 键与可交互 UI&#xff08;如 Button、Toggle、Slider …

Android APP 基于RecyclerView框架工程(知识体系积累)

说明&#xff1a;这个简单的基于RecyclerView的框架作用在于自己可以将平时积累的一些有效demo整合起来&#xff08;比如音视频编解码的、opengles的以及其他也去方向的、随着项目增多&#xff0c;工程量的增加&#xff0c;后期想高效的分析和查找并不容易&#xff09;&#xf…

vscode 环境

这张截图显示的是在VS Code&#xff08;Visual Studio Code&#xff09;中选择Python解释器的界面。不同的Python解释器及其虚拟环境列出了可选项&#xff0c;用户可以根据需要选择合适的解释器来运行Python代码。以下是对截图中信息的详细解释&#xff1a; 解释器选择界面 当…

Java小技能:多级组织机构排序并返回树结构(包含每个层级的子节点和业务数据集合)

文章目录 引言I 实体定义1.1 部门1.2 用户组织机构中间表1.3 树状DTOII 抽取组织机构排序方法2.1 树状排序方法2.2 案例III 查询条件构建3.1 根据部门进行权限控制3.2 注入风险引言 需求: 根据组织机构进行数据授权控制,例如控制船舶、船舶设备、摄像头、港区查看权限。 一…

05_解封装和解码

1. 基本概念 容器就是一种文件格式&#xff0c;比如flv、mkv、mp4等。包含下面5种流以及文件头信息。 流是一种视频数据信息的传输方式&#xff0c;5种流&#xff1a;音频&#xff0c;视频&#xff0c;字幕&#xff0c;附件&#xff0c;数据。 包在ffmpeg中代表已经编码好的一…

【LINUX】pr_info函数开发摸索

1、打印开关可随时控制&#xff0c;开机如果要修改是否打印日志的话&#xff0c;需要修改代码重新编译内核才行&#xff0c;其实如果真要搞&#xff0c;应该有其他方法&#xff1b; 2、打印次数&#xff0c;当前代码里边写的是1000次&#xff0c;其实可以根据传参动态修改打印…