lua(xlua)基础知识点记录二

1. 关于lua函数传参参数

在lua中给function传递参数的时候一般分为两种情况:值传递和引用传递

值传递:

值传递:数字、字符串、布尔值、nil等基本类型通过值传递。函数内部接收的是外部变量的副本,修改副本不会影响原始变量。
虽然我们都知道字符串是引用类型存储的数据,但是在函数传参的时候传递的是指向字符串内存地址的指针值​(即引用的副本),而非原始变量的引用本身

function Test(n)n = n + 1
end
local a = 1
Test(a)
print("输出a:"..a)
-- 结果a仍然是1

引用传递:

​表(table)和函数如果当作函数的参数传递时,传递的时指向具体变量的地址的副本,记住时副本!!可以理解成表本身就是一个指针,把这个指针当作参数传递给函数时,会重新生成一个指针,并且把该变量的指针地址值复制给新生成的指针。所以这种情况下,如果直接操作(增删)都可以正常影响指向的变量数据。但是如果时赋值操作,那么就会修改传递过去的副本指向的内容。

function Test1(t)t.a = 1
endfunction Test2(t)t = {a = 15,b =3}
endfunction Test3(t)t = nil
endlocal t = {a = 10, b = 2}Test1(t)
print("t.a:"..t.a.." t.b:"..t.b)
Test2(t)
print("t.a:"..t.a.." t.b:"..t.b)
Test3(t)
print("t.a:"..t.a.." t.b:"..t.b)

上述代码三次的输出都是: t.a:1 t.b:2,
.
调用Test1的时候直接修改了引用指向的内容,所以修改生效。此时外部的t.a = 1。
.
调用Test2的时候直接把引用副本指向了另一个新表的内存,那么这时候函数内部的t已经和外部传进去的t没有关系了,所以怎么修改都不会对外部的t造成影响。
.
调用Test3的时候和Test2一样,把引用副本指向了空,同样和外部的t没有关联关系了,所以外部t不受影响。

2. 关于c#和lua相互引用(xlua版)

userdata

我们都知道lua中有一种数据类型-userdata
.
userdata 是 Lua 为存储 C/C++ 等外部语言数据而设计的特殊类型,提供了一块原始内存区域,可直接存放结构体、指针、文件句柄等外部对象。它允许 Lua 通过指针或内存块直接操作外部环境的数据,是 Lua 与 C/C++ 交互的核心机制。例如,C 中定义的 struct People 可通过 userdata 传递给 Lua 脚本使用.
.
所以一个语言只要可以和c/c++交互,那么就可以通过userdata和lua交互,这也是c#和lua交互的底层原理。
.

xlua中的c#和lua交互

在xlua中,c#和lua的交互都是通过c这个他们两种语言都能到的媒介实现的。
大致流程如下:

lua call c#

lua调用c# -> 调用c -> 操作虚拟栈对参数压栈 -> 调用c#wrap函数/反射查找函数 ->
把lua函数参数转换成c#类型 -> 完成调用

c# call lua

c#调用lua -> c#调用c函数 -> 通过capi找到lua函数(lua_getglobal) -> c#数据转成lua数据(lua_pushinteger) ->
通过capi调用lua函数(lua_pcall)

xlua中c#和lua相互引用

在xlua框架中,可以很方便的在lua中持有C#的对象变量并使用,反之一样。

lua持有c#对象:

通过上述的userdata了解,我们可以大致了解到,其实c#的变量在lua中是以userdata类型的数据存储的。
事实上在lua中从来没有真正的持有c#的真正变量。

​C#对象在Lua中的表示

在xLua中,C#对象传递到Lua时会被封装为userdata类型。这个userdata并不直接存储C#对象本身,而是存储一个唯一标识符(objId)​,用于关联C#端的实际对象

引用关系的管理(lua持有#)

但是我们也知道c#的gc是并不清楚lua环境中该userdata的引用情况的,如果直接不管lua中是否引用只要c#段就没有引用就GC掉显然不符合我们的需求。所以xlua中设计了ObjectTranslator.cs。
ObjectTranslator通过ObjectPool和ReverseMap维护对象与objId的映射,确保C#对象不被GC回收(只要Lua仍持有userdata)
而在lua中,userdata是被存放在弱引用表中的,只要lua中没有强引用该对象的存在,那么该userdata就可以被lua的gc回收掉,防止lua一致持有着objid而c#无法回收对应对象。

lua对象在c#中的表示:

所有Lua对象在C#中通过LuaBase基类管理,其构造函数调用luaL_ref在Lua注册表中创建引用,析构时调用luaL_unref释放

其实讲了那么多,就是为了理解如下代码:

public class Main{public class TestClass{}public static TestClass MyClassTest;public static TestClass CreateTestClass(){if (MyClassTest == null) MyClassTest = new TestClass();return MyClassTest;}public static void DestroyTestClass(){MyClassTest = null;}
}
local myClass,myClass2,myClass3local function Execute()myClass = CS.Main.CreateTestClass()myClass2 = CS.Main.MyClassTestmyClass3 = myClass2myClass2 = nilcollectgarbage("collect")CS.System.GC.Collect()CS.Main.DestroyTestClass()collectgarbage("collect")CS.System.GC.Collect()
endpcall(Execute)

由上面讲述我们可以知道,一个c#变量在lua中的话,两端是各自持有各自的类型(userdata和TestClass),上述lua代码中的myClass,myClass2和myClass3就是对应的userdata。
.
即使myClass2 = nil后,myClass3和myClass仍然持有该userdata,所以第一次执行双方gc,只会回收掉myClass2。myClass3和myClass以及c#段的MyClassTest都没收影响。
.
那么再来看CS.Main.DestroyMyClass() 这句之后c#侧的MyClassTest引用被置空,注意只是引用实际变量还被lua持有,所以即使执行了C#的gc,真正的对象仍不会被回收掉,因为myClass 和myClass3仍然还存在着并且持有着。
.
那么这时候如何回收掉TestClass对应的数据,只需要再加上
myClass2 = nil
myClass = nil
collectgarbage("collect")
CS.System.GC.Collect()
这样的话lua测得强引用也没了,都可以被回收了

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

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

相关文章

分治算法---归并

1、排序数组 class Solution {vector<int> tmp; public:vector<int> sortArray(vector<int>& nums) {tmp.resize(nums.size());mergeSort(nums,0,nums.size() - 1);return nums;}void mergeSort(vector<int>& nums, int left , int right){if…

《计算机网络》实验报告三 UDP协议分析

目 录 1、实验目的 2、实验环境 3、实验内容 3.1 DNS查询UDP数据分析 3.2 QQ通信UDP数据分析 4、实验结果与分析 4.1 DNS查询UDP数据分析 4.2 QQ通信UDP数据分析 4.3 根据捕获的数据包&#xff0c;分析UDP的报文结构&#xff0c;将UDP协议中个字段名&#xff0c;字段…

Mysql 学习总结(90)—— Mysql 8.0 25 条性能优化实战指南

1. 内存配置优化 # my.cnf 关键内存参数 innodb_buffer_pool_size = 8G # 建议设置为物理内存的70-80% innodb_log_buffer_size = 64M # 日志缓冲区大小 query_cache_size = 0 # MySQL 8.0已移除,确保关闭 tmp_table_size = 256M # 临时表大小 max_…

嵌入式通信DQ单总线协议及UART(一)

文章目录一、DS18B20--DQ单总线1.1 单总线时序结构分析1.1.1 初始化&#xff1a;1.1.2 发送一位1.1.3 接收一位1.1.5 发送字节1.1.6 操作流程1.1.7 数据帧的理解1.1.8 数据帧的理解二、UART2.1 同步通信和异步通信2.2 双工通信2.3 串行通信常用数据校验方式2.3.1 奇偶检验2.3.2…

2025年SEVC SCI2区,利用增强粒子群算法(MR-MPSO)优化MapReduce效率和降低复杂性,深度解析+性能实测

目录1.摘要2.MapReduce-Modified Particle Swarm Optimization (MR-MPSO)3.结果展示4.参考文献5.算法辅导应用定制读者交流1.摘要 大数据的迅猛增长带来了严峻的数据管理挑战&#xff0c;尤其是在数据分布不均的庞大数据库中。由于这种不匹配&#xff0c;传统软件系统的效率大…

10-day07文本分类

文本分类使用场景文本分类任务 文本分类-机器学习贝叶斯算法应用在NLP中的应用 用贝叶斯公式处理文本分类任务 一个合理假设&#xff1a; 文本属于哪个类别&#xff0c;与文本中包含哪些词相关 任务&#xff1a; 知道文本中有哪些词&#xff0c;预测文本属于某类别的概率 贝叶斯…

Apache SeaTunnel详解与部署(最新版本2.3.11)

目录 一、概述 1.1、软件介绍 1.2、解决问题​ 1.3、软件特性​ 1.4、使用用户 1.5、产品对比 二、架构 2.1、运行流程 2.2、连接器​ 2.3、引擎 2.3.1、设计理念 2.3.2、集群管理​ 2.3.3、核心功能​ 2.3.4、引擎对比 三、软件部署 3.1、Docker部署 3.2、发…

pytorch | minist手写数据集

一、神经网络神经网络&#xff08;Neural Network&#xff09;是一种受生物神经系统&#xff08;尤其是大脑神经元连接方式&#xff09;启发的机器学习模型&#xff0c;是深度学习的核心基础。它通过模拟大量 “人工神经元” 的互联结构&#xff0c;学习数据中的复杂模式和规律…

[C/C++安全编程]_[中级]_[如何避免出现野指针]

场景 在Rust里不会出现野指针的情况&#xff0c;那么在C里能避免吗&#xff1f; 说明 野指针是指指向无效内存地址的指针&#xff0c;访问它会导致未定义行为&#xff0c;可能引发程序崩溃、数据损坏或安全漏洞。它是 C/C 等手动内存管理语言中的常见错误&#xff0c;而 Rust…

机器学习基础:从数据到智能的入门指南

一、何谓机器学习​ 在我们的日常生活中&#xff0c;机器学习的身影无处不在。当你打开购物软件&#xff0c;它总能精准推荐你可能喜欢的商品&#xff1b;当你解锁手机&#xff0c;人脸识别瞬间完成&#xff1b;当你使用语音助手&#xff0c;它能准确理解你的指令。这些背后&a…

steam游戏搬砖项目超完整版实操分享

大家好&#xff0c;我是阿阳&#xff0c;今天再次最详细的给大家综合全面的分析讲解下steam搬砖&#xff0c;可以点击后面跳转往期文章了再次解下阿阳网客&#xff1a;关于steam游戏搬砖项目&#xff0c;我想说&#xff01;最早是21年5月份公开朋友圈&#xff0c;初次接触是在2…

vue2 面试题及详细答案150道(21 - 40)

《前后端面试题》专栏集合了前后端各个知识模块的面试题&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

原生前端JavaScript/CSS与现代框架(Vue、React)的联系与区别(详细版)

原生前端JavaScript/CSS与现代框架&#xff08;Vue、React&#xff09;的联系与区别&#xff0c;以及运行环境和条件 目录 引言原生前端技术概述 JavaScript基础CSS基础 现代框架概述 Vue.jsReact 联系与相似性主要区别对比运行环境和条件选择建议总结 引言 在现代Web开发中&…

基于机器视觉的迈克耳孙干涉环自动计数系统设计与实现

基于机器视觉的迈克耳孙干涉环自动计数系统设计与实现 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 摘要 本文设计并实现了一种基于机器视觉的迈克耳孙干涉环自动计数系统。该系统…

设计模式笔记(1)简单工厂模式

最近在看程杰的《大话设计模式》&#xff0c;在这里做一点笔记。 书中主要有两个角色&#xff1a; 小菜&#xff1a;初学者&#xff0c;学生&#xff1b; 大鸟&#xff1a;小菜表哥&#xff0c;大佬。 也按图中的对话形式 01 简单工厂模式 要求&#xff1a;使用c、Java、C#或VB…

Vue3 学习教程,从入门到精通,Vue 3 声明式渲染语法指南(10)

Vue 3 声明式渲染语法指南 本文将详细介绍 Vue 3 中的声明式渲染语法&#xff0c;涵盖所有核心概念&#xff0c;并通过一个完整的案例代码进行演示。案例代码中包含详细注释&#xff0c;帮助初学者更好地理解每个部分的功能和用法。 目录 简介声明式渲染基础 文本插值属性绑…

React hooks——useReducer

一、简介useReducer 是 React 提供的一个高级 Hook&#xff0c;用于管理复杂的状态逻辑。它类似于 Redux 中的 reducer 模式&#xff0c;适合处理包含多个子值、依赖前一个状态或逻辑复杂的状态更新场景。与 useState 相比&#xff0c;useReducer 提供更结构化的状态管理方式。…

SEO中关于关键词分类与布局的方法有那些

前边我们说到关键词挖掘肯定很重要&#xff0c;但如何把挖掘出来的关键词用好更为重要&#xff0c;下边我们就来说说很多seo刚入行的朋友比较头疼的关键词分类问题&#xff0c;为了更直观的感受搭配了表格&#xff0c;希望可以给大家一些帮助!SEO优化之关键词分类​挖掘出的关键…

考研最高效的准备工作是什么

从性价比的角度来说&#xff0c;考研最高效的准备工作是什么呢&#xff1f; 其实就是“卷成绩”。 卷学校中各门课程的成绩&#xff0c;卷考研必考的数学、英语、政治和专业课的成绩。 因为现阶段的考研&#xff0c;最看重的仍然是你的成绩&#xff0c;特别是初试成绩。 有了…

【Linux】基于Ollama和Streamlit快速部署聊天大模型

1.环境准备 1.1 安装Streamlit 在安装Streamlit之前&#xff0c;请确保您的系统中已经正确安装了Python和pip。您可以在终端或命令行中运行以下命令来验证它们是否已安装 python --version pip --version一旦您已经准备好环境&#xff0c;现在可以使用pip来安装Streamlit了。…