当前位置: 首页 > news >正文

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.dtcms.com/a/283630.html

相关文章:

  • Oracle数据泵详解——让数据迁移像“点外卖”一样简单​
  • 数据库管理-第349期 Oracle DB 23.9新特性一览(20250717)
  • python与正则:前后向断言、分组,以及案例练习
  • Xss-labs 1-8关的初步通关
  • 【Linux系统】进程地址空间
  • 时序数据库选型指南 —— 为什么选择 Apache IoTDB?
  • Qt Quick 粒子系统详解
  • 数据呈现高阶技巧:散点图与桑基图的独特价值
  • 从零开始学 Linux 系统安全:基础防护与实战应用
  • 12.9 Mixtral-8x7B核心技术解密:如何用1/3参数实现4倍推理速度碾压LLaMA2?
  • 取消office word中的段落箭头标记
  • 多方案对比分析:后端数据加密策略及实践
  • 菜单权限管理
  • 【Linux】LVS(Linux virual server)
  • zabbix安装(docker-compose)
  • 若依框架开启注册功能全流程指南
  • I3C Host Adapter Pro+ (3)
  • 36.在列表或字典中查找匹配项
  • CrewAI与LangGraph:下一代智能体编排平台深度测评
  • 数据分析全流程指南:从明确目标到数据呈现的实操方法论
  • Kiro vs Cursor: AI IDE 终极对比指南
  • github不能访问怎么办
  • mac OS上docker安装zookeeper
  • 3t车用手动卧式千斤顶设计含8张CAD图纸PDF图
  • 有n棍棍子,棍子i的长度为ai,想要从中选出3根棍子组成周长尽可能长的三角形。请输出最大的周长,若无法组成三角形则输出0。
  • 优先队列的实现
  • 基础算法题
  • 批判式微调(CFT):原理、架构与高效推理训练新范式
  • 基于vue + Cesium 的蜂巢地图可视化实现
  • 学习OpenCV---显示图片