Lua的底层原理与C#交互原理浅析【更新中】
目录
lua底层原理浅析
table底层原理浅析
Lua表的C语言定义
原理和实现
userdata
lua和C#的交互机制(更新中)
基本介绍
Lua 与 C/C++ 的数据交互
Lua 调用 C/C++ 函数
C/C++ 调用 Lua 函数
基元类型传递
对象类型传递
Lua 调用 C#
总结
网上有很多文章写和C#的交互原理,但大多比较复杂,截止到目前为止笔者也只是了解了其中的一部分,目前还在边学边做笔记的阶段,所以说是浅析,后续会做更深入的研究。
lua底层原理浅析
Lua的底层实现是基于C语言,这使得它非常轻量级且高效,同时具有很好的跨平台特性。
-
虚拟机(VM):
- Lua使用基于寄存器的虚拟机来执行编译后的字节码。这与基于堆栈的虚拟机相比,可以减少指令数量和执行时间。
- Lua的字节码是平台无关的,这意味着在一台机器上编译的Lua代码可以在任何其他平台上运行,只要那里有Lua虚拟机。
-
解释器和编译器:
- Lua源代码首先被一个解释器读取,解释器是用C语言编写的。
- 源代码被解析成抽象语法树(AST),然后转换成中间表示,最终编译为字节码。
-
内存管理:
- 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表的实现基于以下原理:
-
双重结构:
- Lua表由两部分组成:一个数组(Array)部分和一个散列(Hash)部分。
- 数组部分用于存储以数字为键的元素,而散列部分用于存储其他类型的键值对。
-
动态调整:
- 当你向表中添加或移除元素时,Lua会动态调整这两部分的大小和存储方式,以保持操作的高效性。
- 例如,如果你主要使用数字键,Lua会倾向于扩展数组部分,而减少散列部分。
-
散列算法:
- 对于非数字键,Lua使用散列算法来快速定位和存储键值对。
- Lua的散列算法旨在减少冲突并快速处理查找、插入和删除操作。
-
数组和散列表的动态重分配:
- Lua会根据表的使用情况动态地重分配内部数组和散列结构,以优化内存使用和访问速度。
-
元表支持:
- Lua表还可以有一个元表(metatable),用于定义该表的特殊行为,比如操作符重载或自定义访问方式。
userdata
在Lua编程语言中,userdata
是一种特殊的数据类型,用于表示任何由应用程序或者C语言代码创建的数据对象。userdata
提供了一种将C中的数据和对象暴露给Lua代码的方式,同时保持类型安全和内存管理的控制。
userdata
在Lua中主要有两种形式:
-
全用户数据(Full userdata):
- 这是一个指向C数据的指针,Lua只负责存储和传递这个指针,不尝试理解或操作其指向的数据。
- 它是一个黑盒,Lua不知道其内部结构,只是简单地通过指针来引用它。
- Lua负责管理这些对象的内存生命周期,通常是通过垃圾回收机制。
-
轻量用户数据(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++ 函数
- 包装函数:将C++函数包装成可供Lua调用的格式,通常是接收一个Lua状态机指针的静态方法。
- 注册函数:在Lua环境中注册这些包装好的函数。
- 调用过程:Lua调用时,通过Lua栈获取参数,执行函数,然后将结果压栈返回。
C/C++ 调用 Lua 函数
- 获取函数:使用
lua_getglobal
获取Lua函数,并将其压入栈。 - 压栈参数:将函数的参数压入栈。
- 执行函数:调用
lua_pcall
执行函数。 - 处理结果:如果无误,从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数据集需要实现两个方法,方法一: 方法二: 运行比较慢的话,…...

深圳鼎信|输电线路防山火视频监控预警装置:森林火灾来袭,安全不留白!
受线路走廊制约和环保要求影响,输电线路大多建立在高山上,不仅可以减少地面障碍物和人类活动的干扰,还能提高线路的抗灾能力和可靠性。但同时也会面临其它的难题,例如森林火灾预防。今天,深圳鼎信智慧将从不同角度分析…...
【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…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...

抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...

《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...
2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案
一、延迟敏感行业面临的DDoS攻击新挑战 2025年,金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征: AI驱动的自适应攻击:攻击流量模拟真实用户行为,差异率低至0.5%,传统规则引…...

Win系统权限提升篇UAC绕过DLL劫持未引号路径可控服务全检项目
应用场景: 1、常规某个机器被钓鱼后门攻击后,我们需要做更高权限操作或权限维持等。 2、内网域中某个机器被钓鱼后门攻击后,我们需要对后续内网域做安全测试。 #Win10&11-BypassUAC自动提权-MSF&UACME 为了远程执行目标的exe或者b…...