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

Lua的底层原理与C#交互原理浅析【更新中】

目录

lua底层原理浅析

table底层原理浅析

Lua表的C语言定义

原理和实现

userdata

lua和C#的交互机制(更新中)

基本介绍

Lua 与 C/C++ 的数据交互

Lua 调用 C/C++ 函数

C/C++ 调用 Lua 函数

基元类型传递

对象类型传递

Lua 调用 C#

总结


网上有很多文章写和C#的交互原理,但大多比较复杂,截止到目前为止笔者也只是了解了其中的一部分,目前还在边学边做笔记的阶段,所以说是浅析,后续会做更深入的研究。

lua底层原理浅析

Lua的底层实现是基于C语言,这使得它非常轻量级且高效,同时具有很好的跨平台特性。

  1. 虚拟机(VM)

    • Lua使用基于寄存器的虚拟机来执行编译后的字节码。这与基于堆栈的虚拟机相比,可以减少指令数量和执行时间。
    • Lua的字节码是平台无关的,这意味着在一台机器上编译的Lua代码可以在任何其他平台上运行,只要那里有Lua虚拟机。
  2. 解释器和编译器

    • Lua源代码首先被一个解释器读取,解释器是用C语言编写的。
    • 源代码被解析成抽象语法树(AST),然后转换成中间表示,最终编译为字节码。
  3. 内存管理

    • Lua使用自动垃圾回收机制来管理内存。它主要使用标记-清扫(mark-and-sweep)算法来回收不再使用的内存。

垃圾回收部分具体可以看我的另外一篇文章

Lua的垃圾回收机制详解-CSDN博客

table底层原理浅析

Lua的表(table)是其最强大的特性之一,它们是动态的关联数组,可以用作普通数组、字典、对象等。在C语言中,Lua的表是通过一种复杂的数据结构实现的,这种结构使得表既能高效地存储和访问序列元素,也能高效地处理散列键值对。

Lua表的C语言定义

在Lua的C源码中,表是通过struct定义的,主要是Table结构。这个结构包括指向数组部分和散列部分的指针,以及这些部分的大小等信息。核心结构大致如下(简化版本,用于说明):

typedef struct lua_Table {CommonHeader;lu_byte flags;  /* 一些标志位 */lu_byte lsizenode;  /* 散列表部分的大小 */unsigned int sizearray;  /* 数组部分的大小 */TValue *array;  /* 数组部分的指针 */Node *node;    /* 散列表部分的指针 */Node *lastfree;  /* 散列表的一个自由位置 */struct Table *metatable;  /* 元表 */GCObject *gclist;
} Table;

原理和实现

Lua表的实现基于以下原理:

  1. 双重结构

    • Lua表由两部分组成:一个数组(Array)部分和一个散列(Hash)部分。
    • 数组部分用于存储以数字为键的元素,而散列部分用于存储其他类型的键值对。
  2. 动态调整

    • 当你向表中添加或移除元素时,Lua会动态调整这两部分的大小和存储方式,以保持操作的高效性。
    • 例如,如果你主要使用数字键,Lua会倾向于扩展数组部分,而减少散列部分。
  3. 散列算法

    • 对于非数字键,Lua使用散列算法来快速定位和存储键值对。
    • Lua的散列算法旨在减少冲突并快速处理查找、插入和删除操作。
  4. 数组和散列表的动态重分配

    • Lua会根据表的使用情况动态地重分配内部数组和散列结构,以优化内存使用和访问速度。
  5. 元表支持

    • Lua表还可以有一个元表(metatable),用于定义该表的特殊行为,比如操作符重载或自定义访问方式。

userdata

在Lua编程语言中,userdata 是一种特殊的数据类型,用于表示任何由应用程序或者C语言代码创建的数据对象。userdata 提供了一种将C中的数据和对象暴露给Lua代码的方式,同时保持类型安全和内存管理的控制。

userdata 在Lua中主要有两种形式:

  1. 全用户数据(Full userdata)

    • 这是一个指向C数据的指针,Lua只负责存储和传递这个指针,不尝试理解或操作其指向的数据。
    • 它是一个黑盒,Lua不知道其内部结构,只是简单地通过指针来引用它。
    • Lua负责管理这些对象的内存生命周期,通常是通过垃圾回收机制。
  2. 轻量用户数据(Light userdata)

    • 这也是一个指针,但Lua不管理其指向的内存。
    • 轻量用户数据相当于一个裸指针,其生命周期由外部代码控制。
    • 它适用于表示轻量级的、生命周期由应用程序控制的对象。

userdata 的主要用途包括:

  • 将C中的对象传递到Lua代码,使得Lua代码可以间接地操作这些对象。
  • 在C和Lua之间共享数据,尤其是当需要在Lua脚本中操作C语言中创建的复杂数据结构时。
  • 实现C和Lua之间的接口调用,尤其是在嵌入Lua到C/C++应用程序时。

使用 userdata 时,通常会配合元表(metatable)来提供对象的方法和属性,这样Lua代码就可以像操作普通的Lua对象那样操作C中的数据。这是实现面向对象编程风格的一种常用手段,特别是在Lua绑定到C/C++库的上下文中。

lua和C#的交互机制(更新中)

参考文章:

C#与XLua交互原理 - 知乎 (zhihu.com)

基本介绍

  • Lua 虚拟机:Lua 是由 C/C++ 实现的,因此它可以直接与宿主程序(如Unity)进行通信。
  • C# 与 Lua 交互:C# 通过 P/Invoke(平台调用)方式调用 Lua 虚拟机函数。这意味着 C# 可以通过 C/C++ 层与 Lua 进行数据交互。
  • xLua 中的 P/Invoke:xLua 提供的 P/Invoke 调用接口主要在 LuaDLL.cs 文件中。

Lua 与 C/C++ 的数据交互

  • 虚拟栈:Lua 提供了一个虚拟栈用于数据交换。所有类型的数据交换都通过这个栈完成。
  • 栈索引:Lua 有两种索引方式操作虚拟栈 — 正数索引(1表示栈底)和反向索引(-1表示栈顶)。

Lua 调用 C/C++ 函数

  1. 包装函数:将C++函数包装成可供Lua调用的格式,通常是接收一个Lua状态机指针的静态方法。
  2. 注册函数:在Lua环境中注册这些包装好的函数。
  3. 调用过程:Lua调用时,通过Lua栈获取参数,执行函数,然后将结果压栈返回。

C/C++ 调用 Lua 函数

  1. 获取函数:使用 lua_getglobal 获取Lua函数,并将其压入栈。
  2. 压栈参数:将函数的参数压入栈。
  3. 执行函数:调用 lua_pcall 执行函数。
  4. 处理结果:如果无误,从Lua虚拟栈中取出结果。

基元类型传递

  • 直接通过 C API 传递,如 lua_pushboolean, lua_pushnumber 等。

对象类型传递

  • 过程:C# 对象在Lua中通过表(table)模拟,传递的是索引,同时需要将C#类型信息注册到Lua。
  • userdata:C# 对象在 Lua 中对应的是一个 userdata,用于保持与C#对象的联系。
  • 元表:为 userdata 设置的元表包含了对象的类型信息,如成员方法、属性等。

Lua 调用 C#

  • Lua 通过调用 C# 包装好的静态方法来实现调用,这些方法转换Lua的调用为C#函数的调用。
  • 使用元表信息来确定要调用的C#方法和属性。
  • 函数通过Lua的栈接收参数,参数按顺序入栈。

总结

在 Unity 中,xLua 框架通过 C API 层实现 C# 和 Lua 的交互。Lua 和 C# 之间的调用主要是通过虚拟栈来传递数据和参数。C# 对象在Lua中通过 userdata 表示,而 C# 与 Lua 的函数调用则是通过预先包装好的静态方法来实现。这个过程涉及多个层面的数据转换和类型匹配,但最终实现了两种语言间高效的互操作性。

相关文章:

Lua的底层原理与C#交互原理浅析【更新中】

目录 lua底层原理浅析 table底层原理浅析 Lua表的C语言定义 原理和实现 userdata lua和C#的交互机制(更新中) 基本介绍 Lua 与 C/C 的数据交互 Lua 调用 C/C 函数 C/C 调用 Lua 函数 基元类型传递 对象类型传递 Lua 调用 C# 总结 网上有很…...

鸿蒙项目二—— 注册和登录

此部分和上篇文章是连续剧 ,如果需要,请查看 一、注册 import http from ohos.net.http; Entry Component struct Reg {// 定义数据:State username: string "";State userpass: string "";State userpass2: string …...

Dijkstra(迪杰斯特拉)算法总结

知识概览 Dijkstra算法适用于解决所有边权都是正数的最短路问题。Dijkstra算法分为朴素的Dijkstra算法和堆优化版的Dijkstra算法。朴素的Dijkstra算法时间复杂度为,适用于稠密图。堆优化版的Dijkstra算法时间复杂度为,适用于稀疏图。稠密图的边数m和是一…...

设计模式?!

如何解决复杂性 链接:不同的设计模式实例代码(更新中) 分解 人们面对复杂性有一个常见的做法:即分而治之,将大问题分解为多个小问题,将复杂问题分解为多个简单问题。 抽象 更高层次来讲,人们处…...

Pytorch项目,肺癌检测项目之三

成功获取到数据之后,我们需要将数据放到Pytorch里面去处理,我们需要将其转换成Dataset数据集,方便去使用相同的API。要转换成Dataset数据集需要实现两个方法,方法一: 方法二: 运行比较慢的话&#xff0c…...

深圳鼎信|输电线路防山火视频监控预警装置:森林火灾来袭,安全不留白!

受线路走廊制约和环保要求影响,输电线路大多建立在高山上,不仅可以减少地面障碍物和人类活动的干扰,还能提高线路的抗灾能力和可靠性。但同时也会面临其它的难题,例如森林火灾预防。今天,深圳鼎信智慧将从不同角度分析…...

【Bash/Shell】知识总结

文章目录 1. 总体认识1.1. Shell概述1.2. 第一个Shell脚本1.3. 注释 2. 变量2.1. 定义变量2.2. 使用变量2.3. 只读变量2.4. 删除变量2.5. 变量类型2.5.1. 字符串变量2.5.2. 整数变量2.5.3. 数组变量2.5.4. 环境变量2.5.5. 特殊变量 3. 输出3.1. echo命令3.2. printf命令 4. 运算…...

单例模式(C++实现)

RAII运用 只能在栈上创建对象 只能在堆上创建的对象 单例模式 设计模式 懒汉模式 解决线程安全 优化 饿汉模式 饿汉和懒汉的区别 线程安全与STL与其他锁...

ElasticSearch 聚合统计

聚合统计 度量聚合:求字段的平均值,最小值,最大值,总和等 桶聚合:将文档分成不同的桶,桶的划分可以根据字段的值,范围,日期间隔 管道聚合:在桶聚合的结果上执行进一步计…...

SpringIOC之MethodBasedEvaluationContext

博主介绍:✌全网粉丝5W+,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验✌ 博主作品:《Java项目案例》主要基于SpringBoot+MyBatis/MyBatis-plus+…...

【网络安全 | 网络协议】结合Wireshark讲解TCP三次握手

前言 TCP(传输控制协议)是一种面向连接的、可靠的传输层协议。在建立 TCP 连接时,需要进行三次握手,防止因为网络延迟、拥塞等原因导致的数据丢失或错误传输,确保双方都能够正常通信。 TCP三次握手在Wireshark数据包中…...

钦丰科技(安徽)股份有限公司携卫生级阀门管件盛装亮相2024发酵展

钦丰科技(安徽)股份有限公司携卫生级阀门管件盛装亮相2024济南生物发酵展! 展位号:2号馆A65展位 2024第12届国际生物发酵产品与技术装备展览会(济南)于3月5-7日在山东国际会展中心盛大召开,展会同期将举办30余场高质…...

Python模拟动态星空

前言 今天,我们来用Python做个星空。 一、模拟星空 1,.首先导入所需要的库: from turtle import * from random import random, randint 2.初始画面: screen Screen() width, height 800, 600 screen.setup(width, height) screen.tit…...

最新技术整理3款开源免费直播推流工具,实现实时视频推流、视频拉流,目标端可以是服务器、云平台、移动设备等(附源码)

最新技术整理3款开源免费直播推流工具,实现实时视频推流、视频拉流,目标端可以是服务器、云平台、移动设备等(附源码)。 什么是推流? 视频推流是指将实时的视频数据从一个源端发送到一个或多个目标端的过程。推流的源…...

shell ——数组

数组中可以存放多个值,Bash Shell只能支持以为数字,初始化时不需要定义数组大小。 数组中元素下标从0开始。 数组的定义 shell数组用括号来表示,元素用空格分割开。 array_name(value1 value2 value3 ...) 给一个简单数组例子 cat firs…...

GO语言基础笔记(五):包的介绍

在Go语言中,包(package)是代码组织和重用的基本单位。Go的标准库中包含了许多实用的包,它们提供了从基础数据处理到复杂网络编程等各种功能。下面是一些常用的Go标准库包及其作用的介绍: 目录 1. fmt 2. net/http …...

【Unity6.0+AI】Sentis加载模型识别手写数字案例实现

按照国际惯例,看效果: 素材准备: 自己在PS中绘制黑底白字手写字体,导出jpg,尺寸28*28! 素材设置 基本步骤 准备工作:从 ONNX Model Zoo 下载手写识别 ONNX 模型文件 【下载模型】MNIST 手写数字识别模型 mnist-12.onnx,并将其拖入项目窗口的 Assets 文件夹。 【下载模…...

VScode跑通Remix.js官方的contact程序开发过程

目录 1 引言 2 安装并跑起来 3 设置根路由 4 用links来添加风格资源 ​5 联系人路由的UI 6 添加联系人的UI组件 7 嵌套路由和出口 8 类型推理 9 Loader里的URL参数 10 验证参数并抛出响应 书接上回,我们已经跑通了remix的quick start项目,接下…...

讲座思考 | 周志华教授:新型机器学习神经元模型的探索

12月22日,有幸听了南京大学周志华教授题为“新型机器学习神经元模型的探索”的讲座。现场热闹非凡,大家像追星一样拿着“西瓜书”找周教授签名。周教授讲得依旧循循善诱,由浅入深,听得我很入迷,故作此记。 周教授首先就…...

docker构建镜像及项目部署

文章目录 练习资料下载一、docker基础1. 基本概念2. docker常见命令3. 命令别名4. 数据卷 二、docker自定义镜像1. 了解镜像结构2. 了解Dockerfile3. 构建Dockerfile文件,完成自定义镜像 三、网络1. docker常见网络命令2. docker自带虚拟网络3. 自定义网络 四、dock…...

python/java环境配置

环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

Python如何给视频添加音频和字幕

在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...

实战设计模式之模板方法模式

概述 模板方法模式定义了一个操作中的算法骨架&#xff0c;并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下&#xff0c;重新定义算法中的某些步骤。简单来说&#xff0c;就是在一个方法中定义了要执行的步骤顺序或算法框架&#xff0c;但允许子类…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...

医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor

1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...