一篇文章讲明白luauserdata

简介: 一篇文章讲明白luauserdata

本文内容基于版本:Lua 5.3.0

概述

Userdata在储存形式上和字符串十分类似,也是在代表该数据类型的结构体Udata后面直接追加数据内容部分。Userdata可以看成是拥有独立元表,没有内部化处理,也不需要追加'\0'字符的字符串 。从底层来看,Userdata和字符串存储的都是二进制数据,因此它们必然有一定的共同性,而由于两者用途不同又展现出一定的差异性。阅读Lua源码可以看到Userdata和字符串的实现代码被放在一起, 两者的API也以luaS打头。

Udata结构

? Udata结构的声明

Lua中Userdata对应的C结构为Udata,该类型定义在lobject.h中。

// lobject.h

/

Common Header for all collectable objects (in macro form, to be

included in other objects)

/

#define CommonHeader GCObject next; lu_byte tt; lu_byte marked

// lobject.h

/

Header for userdata; memory area follows the end of this structure

(aligned according to 'UUdata'; see next).

/

typedef struct Udata {

CommonHeader;

lubyte ttuv; / user value's tag /

struct Table metatable;

sizet len; / number of bytes /

union Value user; / user value /

} Udata;

CommonHeader : 用于GC的信息。

ttuv :

metatable : Userdata关联的元表。

len :

user :

? Udata存储结构图

Lua中Userdata数据内容部分并未分配独立的内存来存储,而是直接追加在Udata结构的后面。Udata存储结构如下图:

? Userdata对象 = Udata结构 + 实际用户数据

? Udata结构 = GCObject 指针 + Userdata信息数据

创建Userdata

? Userdata创建的函数调用图

Userdata创建过程的核心函数是luaS_newudata,而函数lua_newuserdata作为luaS_newudata的包裹函数旨在屏蔽Udata的内部细节,而只提供给用户指向存储实际数据部分的内存指针。下面就这两个函数着重进行分析。

? luaS_newudata

// lstring.h

#define sizeludata(l) (sizeof(union UUdata) + (l))

// lstring.h

LUAI_FUNC Udata luaS_newudata (lua_State L, size_t s);

// lstring.c

Udata luaS_newudata (lua_State L, size_t s) {

Udata u;

GCObject *o;

if (s > MAX_SIZE - sizeof(Udata))

luaM_toobig(L);

o = luaC_newobj(L, LUA_TUSERDATA, sizeludata(s));

u = gco2u(o);

u->len = s;

u->metatable = NULL;

setuservalue(L, u, luaO_nilobject);

return u;

}//代码效果参考:http://www.ezhiqi.com/bx/art_6973.html

相关文章
|
C++
UE4/5中DataTable数据表的使用
UE4/5中DataTable数据表的使用
2243 1
UE4/5中DataTable数据表的使用
|
10月前
|
存储 人工智能 Shell
Lua与C语言接口编程实战指南:打造高性能、灵活的程序
本文深入介绍了 Lua 与 C 语言的交互机制,重点分析了 Lua 作为胶水语言在嵌入式系统、游戏开发(如 Skynet、OpenResty)中的应用。内容涵盖 Lua 环境搭建、虚拟栈管理、C 与 Lua 的相互调用、闭包、Userdata 和注册表的使用等核心技术,并结合代码示例讲解了如何在实际项目中实现 Lua 与 C 的高效交互,适合希望掌握 Lua 扩展与嵌入开发的工程师参考学习。
1193 0
|
3月前
|
Linux API 云计算
OpenClaw怎么部署?OpenClaw 阿里云计算巢、本地多系统部署接入千问Qwen3-Max大模型教程
2026年,OpenClaw(原Clawdbot)凭借轻量化、高扩展、全场景适配的特性,已成为AI自动化与智能交互的主流框架。阿里云轻量服务器凭借**秒级部署、预集成环境、低成本运维**的优势,成为OpenClaw云端部署的首选方案;同时,本地MacOS、Linux、Windows11部署可满足开发调试、离线运行等个性化需求。本文基于2026年最新版本,完整拆解**阿里云轻量服务器秒级部署OpenClaw**、**本地多系统部署**、**阿里云千问Qwen3-Max API配置**、**免费Coding Plan API配置**全流程,附可直接复制的代码命令与高频问题解答
444 2
|
缓存 Ubuntu Linux
Docker Buildx 简介与安装指南
Docker Buildx 是一个强大的工具,提供了多架构构建、并行构建和高级缓存管理等功能。通过正确安装和配置 Buildx,可以显著提升 Docker 镜像的构建效率和灵活性。希望本文能帮助你更好地理解和使用 Docker Buildx,以提高开发和部署的效率。
7271 16
|
JavaScript 前端开发 编译器
还不会ts?一文带你打开ts的大门
该文章详细介绍了TypeScript的基础知识,包括类型系统、类、接口、泛型等核心概念,并通过具体示例展示了如何使用TypeScript进行项目初始化和模块化开发,帮助读者快速掌握TypeScript的基本用法。
1401 133
还不会ts?一文带你打开ts的大门
|
数据可视化 开发者 C++
Qt(C++)使用QChart静态显示3个设备的温度变化曲线
QChart模块是Qt Charts库的基础,提供了用于创建和显示各种类型图表的类和接口。Qt Charts库是一个功能丰富、易于使用的数据可视化工具库,可以帮助开发者在应用程序中添加漂亮而又交互性强的图表。
685 1
Qt(C++)使用QChart静态显示3个设备的温度变化曲线
|
机器学习/深度学习 编解码 人工智能
什么样才算好图——从生图模型质量度量方法看模型能力的发展(下)
什么样才算好图——从生图模型质量度量方法看模型能力的发展(下)
1403 1
|
安全 程序员 编译器
【C++ 异常 】深入了解C++ 异常机制中的 terminate()处理 避免不必要的错误(一)
【C++ 异常 】深入了解C++ 异常机制中的 terminate()处理 避免不必要的错误
1296 1
|
编译器 C#
【.NET Core】C#编程规范
【.NET Core】C#编程规范
927 0
|
C++ 开发者 缓存
面向 C++ 的现代 CMake 教程(四)(1)
面向 C++ 的现代 CMake 教程(四)
456 0