跳到主要内容

class 类型 Marshal 设计规范

本文档描述 引用类型(class、interface、string、array、delegate 实例等)在 Lua 与 C# 之间的编组规则,与 ../../type-system-spec.md §3(class 实例 userdata)、../../marshal/index.md 衔接。

平台原则: Mono 与 Il2Cpp 的 Lua 可见语义一致;class 实例默认 GCHandle + userdata(Il2Cpp:ObjectRegistry)。


1. 默认 by-value 规则(概要)

方向Lua 形态说明
C# → Luaclass userdataPushConstructorInstance / ObjectRegistry
Lua → C#userdata / nilTryGetBoxedTarget;须可赋值给目标类型
stringstring / nil非 userdata
arrayarray userdata../../type-system-spec.md §7

详细字段、方法访问见 ../../type-system-spec.md §3。


2. ref / out / in 引用类型形参(Lua → C#)

总览见 ../../marshal/index.md §3。本节补充 引用类型 特有规则。

2.1 Pop 行为

Lua 实参行为
class / string / array userdatastring / nilby-val 读入引用(对象 ID)
其他可转换形态拷贝进 临时 ref 槽(与值类型拷贝分支相同)

均不报错(与值类型 §3.1 一致)。

2.2 写回:仅「共享引用」,无 rebind

C# 侧操作Lua 侧
refParam = otherObject重新绑定 ref)不回写;Lua 变量 / userdata 仍指向原对象
可变对象 原地修改(ref StringBuilderref List<T>、改数组元素)可见(同一托管对象)
ref string 赋新字符串不回写(string 不可变,语义等同 rebind)
local s = "hello"
CS.Demo.ChangeString(s) -- void ChangeString(ref string s) { s = "world"; }
-- s 仍为 "hello"

local sb = StringBuilder("hi")
CS.Demo.Append(sb, "!") -- void Append(ref StringBuilder sb, string t) { sb.Append(t); }
-- sb 内容已变(共享引用)

2.3 与 zlua.new_ref 的关系

zlua.new_ref 仅接受值类型../../lib-spec.md §6)。不要对 class / string 使用 new_refref MyClass 直接传 userdata 或 nil 即可。


3. 相关文档

文档内容
../../marshal/index.md §3ref/in/out 总规则
../../marshal/struct.md §6.2值类型 StructUserData / ref
../../marshal/function.mddelegate 形参(无 ref)