- 所有父级接口:
Constable
- 所有已知的实现类:
GroupLayout
,SequenceLayout
,ValueLayout
ValueLayout
)和 padding layouts ,顾名思义,用于表示内存段的一部分,其内容应被忽略,并且主要是出于对齐原因而存在(请参阅 paddingLayout(long)
)。一些常见的值布局常量在 MemoryLayouts
类中定义。
更复杂的布局可以从更简单的布局中派生出来:a sequence layout 表示一个或多个元素布局的重复(请参阅 SequenceLayout
); a group layout 表示(通常)异构成布局的聚合(请参阅 GroupLayout
)。
例如,考虑以下 C 中的结构声明:
上面的声明可以使用布局对象建模,如下所示:typedef struct { char kind; int value; } TaggedValues[5];
SequenceLayout taggedValues = MemoryLayout.sequenceLayout(5, MemoryLayout.structLayout( MemoryLayout.valueLayout(8, ByteOrder.nativeOrder()).withName("kind"), MemoryLayout.paddingLayout(24), MemoryLayout.valueLayout(32, ByteOrder.nativeOrder()).withName("value") ) ).withName("TaggedValues");
该接口的所有实现都必须是 value-based ;程序应将 equal 的实例视为可互换的,并且不应使用实例进行同步,否则可能会发生不可预测的行为。例如,在未来的版本中,同步可能会失败。应使用 equals
方法进行比较。
非平台类不应直接实现 MemoryLayout。
除非另有指定,否则将 null
参数或包含一个或多个 null
元素的数组参数传递给此类中的方法会导致抛出 NullPointerException
。
大小、对齐和字节顺序
所有布局都有尺寸;值和填充布局的布局大小始终明确表示;这意味着无论在哪个平台上使用,布局描述总是具有相同的位大小。对于派生布局,大小计算如下:- 对于元素布局为 E 且大小为 L 的 finite 序列布局 S , S 的大小为 E 的大小乘以 L
- unbounded 序列布局的大小是 unknown
- 对于具有成员布局 M1、M2、...Mn 的组布局 G,其大小分别为 S1、S2、...Sn,G 的大小为 S1 + S2 + ... + Sn 或 max(S1, S2, ... Sn) 取决于组是 struct 还是 union , 分别
此外,所有布局都有一个 natural alignment 可以推断如下:
- 对于 padding 布局 L ,自然对齐是 1,不管它的大小;也就是说,在没有显式对齐约束的情况下,填充布局不应影响它嵌套到的组布局的对齐约束
- 对于大小为 N 的值布局 L,L 的自然对齐方式为 N
- 对于元素布局为 E 的序列布局 S , S 的自然对齐是 E 的自然对齐
- 对于组布局 G 和成员布局 M1 , M2 , ... Mn 其对齐方式分别为 A1 , A2 , ... An , G 的自然对齐方式为 max(A1, A2 ... An)
withBitAlignment(long)
),这对于描述超对齐布局很有用。
所有值布局都有一个 explicit 字节顺序(请参阅 ByteOrder
),该顺序是在创建布局时设置的。
布局路径
layout path 源自 root 布局(通常是组或序列布局),并终止于嵌套在根布局内的布局 - 这是布局路径的布局 selected。布局路径通常表示为一个或多个MemoryLayout.PathElement
实例的序列。
例如,布局路径对于获取另一个布局内任意嵌套布局的偏移量(参见 bitOffset(PathElement...)
)、快速获取与所选布局相对应的内存访问句柄(参见 varHandle(Class, PathElement...)
)、选择另一个布局内的任意嵌套布局(请参阅 select(PathElement...)
,或将嵌套布局元素转换到另一个布局内(请参阅 map(UnaryOperator, PathElement...)
)。
这样的 layout paths 可以使用此类中的方法以编程方式构建。例如,给定如上构造的taggedValues
布局实例,我们可以获得first序列元素中名为value
的成员布局的偏移量,以位为单位,如下所示:
同样,我们可以选择名为long valueOffset = taggedValues.bitOffset(PathElement.sequenceElement(0), PathElement.groupElement("value")); // yields 32
value
的成员布局,如下:
并且,我们还可以将名为MemoryLayout value = taggedValues.select(PathElement.sequenceElement(), PathElement.groupElement("value"));
value
的布局替换为其他布局,如下所示:
也就是说,上面的声明与下面的声明相同,更冗长:MemoryLayout taggedValuesWithHole = taggedValues.map(l -> MemoryLayout.paddingLayout(32), PathElement.sequenceElement(), PathElement.groupElement("value"));
布局路径可以包含一个或多个 free dimensions 。例如,遍历未指定序列元素的布局路径(即,使用MemoryLayout taggedValuesWithHole = MemoryLayout.sequenceLayout(5, MemoryLayout.structLayout( MemoryLayout.valueLayout(8, ByteOrder.nativeOrder()).withName("kind"), MemoryLayout.paddingLayout(32), MemoryLayout.paddingLayout(32) ));
MemoryLayout.PathElement.sequenceElement()
方法获取其中一个路径组件)具有额外的自由维度,该维度必须在运行时绑定。当从布局获取内存访问 var 句柄时,这一点很重要,如以下代码所示:
由于上例中构造的布局路径恰好具有一个自由维度(因为它没有指定应从封闭序列布局中选择名为VarHandle valueHandle = taggedValues.varHandle(int.class, PathElement.sequenceElement(), PathElement.groupElement("value"));
value
的 which 成布局),因此内存访问 var 句柄 valueHandle
将具有 additional long
访问坐标。
具有自由尺寸的布局路径也可用于使用 bitOffset(PathElement...)
或 byteOffsetHandle(PathElement...)
方法创建偏移计算方法句柄。同样,自由维度被转换为创建的方法句柄的long
参数。通过在调用方法句柄时提供这些索引,方法句柄可用于计算不同索引处的序列元素的偏移量。例如:
MethodHandle offsetHandle = taggedValues.byteOffsetHandle(PathElement.sequenceElement(), PathElement.groupElement("kind")); long offset1 = (long) offsetHandle.invokeExact(1L); // 8 long offset2 = (long) offsetHandle.invokeExact(2L); // 16
布局属性
布局可以选择与一个或多个 attributes 相关联。布局属性形成 name/value 对,其中名称为String
,值为 Constable
。布局属性最常见的形式是 layout name (请参阅 LAYOUT_NAME
),这是一个可以与内存布局关联的自定义名称,并且可以在构造 layout paths 时引用。
- 实现要求:
- 此接口的实现是不可变的、线程安全的和 value-based 。
-
内部类总结
-
字段摘要
-
方法总结
修饰符和类型方法描述返回具有给定名称的属性(如果存在)。返回与此布局关联的属性名称流。long
返回与此布局关联的对齐约束,以位表示。default long
bitOffset
(MemoryLayout.PathElement... elements) 计算由给定布局路径选择的布局的偏移量(以位为单位),其中该路径被认为植根于此布局。default MethodHandle
bitOffsetHandle
(MemoryLayout.PathElement... elements) 创建一个方法句柄,可用于计算由给定布局路径选择的布局的偏移量(以位为单位),其中该路径被视为植根于此布局。long
bitSize()
计算布局大小,以位为单位。default long
返回与此布局关联的对齐约束,以字节表示。default long
byteOffset
(MemoryLayout.PathElement... elements) 计算由给定布局路径选择的布局的偏移量(以字节为单位),其中该路径被认为是此布局的根。default MethodHandle
byteOffsetHandle
(MemoryLayout.PathElement... elements) 创建一个方法句柄,可用于计算给定布局路径选择的布局的偏移量(以字节为单位),其中该路径被视为植根于此布局。default long
byteSize()
计算布局大小,以字节为单位。Optional<? extends DynamicConstantDesc<? extends MemoryLayout>>
boolean
比较指定对象与此布局是否相等。int
hashCode()
返回此布局的哈希码值。boolean
hasSize()
这个布局有指定的尺寸吗?boolean
这是一个填充布局(例如从paddingLayout(long)
创建的布局)吗?default MemoryLayout
map
(UnaryOperator<MemoryLayout> op, MemoryLayout.PathElement... elements) 创建此布局的转换副本,其中从以该布局为根的路径中选择的布局被替换为应用给定操作的结果。name()
返回与此布局关联的name(如果有)。static MemoryLayout
paddingLayout
(long size) 创建具有给定大小的新填充布局。default MemoryLayout
select
(MemoryLayout.PathElement... elements) 从以该布局为根的路径中选择布局。static SequenceLayout
sequenceLayout
(long elementCount, MemoryLayout elementLayout) 使用给定的元素布局和元素计数创建新的序列布局。static SequenceLayout
sequenceLayout
(MemoryLayout elementLayout) 创建一个新的序列布局,具有无限的元素计数和给定的元素布局。default MethodHandle
sliceHandle
(MemoryLayout.PathElement... elements) 创建一个方法句柄,给定内存段,该方法句柄返回与给定布局路径选择的布局相对应的slice,其中该路径被视为以此布局为根。static GroupLayout
structLayout
(MemoryLayout... elements) 使用给定的成布局创建新的struct组布局。toString()
返回此布局的字符串表示形式。static GroupLayout
unionLayout
(MemoryLayout... elements) 使用给定的成布局创建新的union组布局。static ValueLayout
valueLayout
(long size, ByteOrder order) 创建给定字节顺序和大小的值布局。default VarHandle
varHandle
(Class<?> carrier, MemoryLayout.PathElement... elements) 创建一个内存访问变量句柄,可用于在给定布局路径选择的布局中取消引用内存,其中该路径被认为植根于此布局。withAttribute
(String name, Constable value) 返回一个新的内存布局,它具有与此布局相同的属性,以及新指定的属性。withBitAlignment
(long bitAlignment) 创建一个具有所需对齐约束的新布局。创建一个具有所需布局 name 的新布局。
-
字段详细信息
-
LAYOUT_NAME
用于指定内存布局的 name 属性的属性名称(请参阅name()
和withName(String)
)。- 参见:
-
-
方法详情
-
describeConstable
Optional <? extends DynamicConstantDesc <? extends MemoryLayout >> describeConstable()- 指定者:
describeConstable
在接口Constable
中- 返回:
-
包含生成的标称描述符的
Optional
,如果无法构造,则为空Optional
。
-
hasSize
boolean hasSize()这个布局有指定的尺寸吗?如果布局是(或包含)未指定大小的序列布局,则布局没有指定的大小(请参阅SequenceLayout.elementCount()
)。值布局(请参阅ValueLayout
)和填充布局(请参阅paddingLayout(long)
) always 具有指定的大小,因此在这些情况下此方法始终返回true
。- 返回:
true
,如果此布局具有指定的大小。
-
bitSize
long bitSize()计算布局大小,以位为单位。- 返回:
- 布局大小,以位为单位。
- 抛出:
UnsupportedOperationException
- 如果布局是或包含未指定大小的序列布局(请参阅SequenceLayout
)。
-
byteSize
default long byteSize()计算布局大小,以字节为单位。- 返回:
- 布局大小,以字节为单位。
- 抛出:
UnsupportedOperationException
- 如果布局是或包含未指定大小的序列布局(请参阅SequenceLayout
),或者如果bitSize()
不是 8 的倍数。
-
name
返回与此布局关联的name(如果有)。这等效于以下代码:
attribute(LAYOUT_NAME).map(String.class::cast);
- 返回:
- 布局name(如果有)。
- 参见:
-
withName
创建一个具有所需布局 name 的新布局。这等效于以下代码:
withAttribute(LAYOUT_NAME, name);
- 参数:
name
- 布局名称。- 返回:
- 一个与此布局相同的新布局,除了与其关联的 name 之外。
- 参见:
-
bitAlignment
long bitAlignment()返回与此布局关联的对齐约束,以位表示。布局对齐定义了 2 的幂A
,这是布局的逐位对齐。如果A <= 8
那么A/8
是正确指向此布局的任何指针必须对齐的字节数。因此:A=8
表示unaligned(通常意义上的),这在数据包中很常见。A=64
表示字对齐(在 LP64 上),A=32
int 对齐,A=16
short 对齐等。A=512
是 x86/SV ABI(对于 AVX-512 数据)要求的最严格对齐。
withBitAlignment(long)
),则此方法返回与此布局关联的 自然排列 约束(以位为单位)。- 返回:
- 布局对齐约束,以位为单位。
-
byteAlignment
default long byteAlignment()返回与此布局关联的对齐约束,以字节表示。布局对齐定义了 2 的幂A
,这是布局的字节对齐方式,其中A
是正确指向此布局的任何指针必须对齐的字节数。因此:A=1
表示unaligned(通常意义上的),这在数据包中很常见。A=8
表示字对齐(在 LP64 上),A=4
int 对齐,A=2
short 对齐等。A=64
是 x86/SV ABI(用于 AVX-512 数据)要求的最严格对齐。
withBitAlignment(long)
),则此方法返回与此布局关联的 自然排列 约束(以字节为单位)。- 返回:
- 布局对齐约束,以字节为单位。
- 抛出:
UnsupportedOperationException
- 如果bitAlignment()
不是 8 的倍数。
-
withBitAlignment
创建一个具有所需对齐约束的新布局。- 参数:
bitAlignment
- 布局对齐约束,以位表示。- 返回:
- 与此布局相同的新布局,除了与之关联的对齐约束。
- 抛出:
IllegalArgumentException
- 如果bitAlignment
不是 2 的幂,或者小于 8。
-
attribute
返回具有给定名称的属性(如果存在)。- 参数:
name
- 属性名称- 返回:
- 具有给定名称的属性(如果存在)。
-
withAttribute
返回一个新的内存布局,它具有与此布局相同的属性,以及新指定的属性。如果此布局已包含具有相同名称的属性,则现有属性值将在返回的布局中被重写。- 参数:
name
- 属性名称。value
- 属性值。- 返回:
- 一个新的内存布局,它具有与此布局相同的属性,以及新指定的属性。
-
attributes
返回与此布局关联的属性名称流。- 返回:
- 与此布局关联的属性名称流。
-
bitOffset
计算由给定布局路径选择的布局的偏移量(以位为单位),其中该路径被认为植根于此布局。- 参数:
elements
- 布局路径元素。- 返回:
elements
中的布局路径选择的布局的偏移量(以位为单位)。- 抛出:
IllegalArgumentException
- 如果布局路径未选择嵌套在此布局中的任何布局,或者布局路径包含一个或多个选择多个序列元素索引的路径元素(请参阅MemoryLayout.PathElement.sequenceElement()
和MemoryLayout.PathElement.sequenceElement(long, long)
)。UnsupportedOperationException
- 如果布局路径遍历的布局之一具有未指定的大小。NullPointerException
- 如果elements == null
,或者elements
中的任何元素是null
。
-
bitOffsetHandle
创建一个方法句柄,可用于计算由给定布局路径选择的布局的偏移量(以位为单位),其中该路径被视为植根于此布局。返回的方法句柄的返回类型为
long
,并且具有与提供的布局路径中的自由维度一样多的long
参数类型(请参阅MemoryLayout.PathElement.sequenceElement()
,其中参数的顺序对应于路径元素的顺序。返回的方法handle 可用于计算类似于bitOffset(PathElement...)
的布局偏移量,但仅在调用方法句柄时指定一些序列索引。方法句柄返回的最终偏移量计算如下:
offset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
x_1
、x_2
、...x_n
是作为long
参数提供的 dynamic 值,而c_1
、c_2
、 ...c_m
是 static 偏移常量和s_0
,s_1
, ...s_n
是 static 步幅常数,它们源自布局路径.- 参数:
elements
- 布局路径元素。- 返回:
- 一个方法句柄,可用于计算给定布局路径元素指定的布局元素的位偏移,当提供缺少的序列元素索引时。
- 抛出:
IllegalArgumentException
- 如果布局路径包含一个或多个选择多个序列元素索引的路径元素(请参阅MemoryLayout.PathElement.sequenceElement(long, long)
)。UnsupportedOperationException
- 如果布局路径遍历的布局之一具有未指定的大小。
-
byteOffset
计算由给定布局路径选择的布局的偏移量(以字节为单位),其中该路径被认为是此布局的根。- 参数:
elements
- 布局路径元素。- 返回:
elements
中的布局路径选择的布局的偏移量(以字节为单位)。- 抛出:
IllegalArgumentException
- 如果布局路径未选择嵌套在此布局中的任何布局,或者布局路径包含一个或多个选择多个序列元素索引的路径元素(请参阅MemoryLayout.PathElement.sequenceElement()
和MemoryLayout.PathElement.sequenceElement(long, long)
)。UnsupportedOperationException
- 如果布局路径遍历的布局之一具有未指定的大小,或者如果bitOffset(elements)
不是 8 的倍数。NullPointerException
- 如果elements == null
,或者elements
中的任何元素是null
。
-
byteOffsetHandle
创建一个方法句柄,可用于计算给定布局路径选择的布局的偏移量(以字节为单位),其中该路径被视为植根于此布局。返回的方法句柄的返回类型为
long
,并且具有与提供的布局路径中的自由维度一样多的long
参数类型(请参阅MemoryLayout.PathElement.sequenceElement()
,其中参数的顺序对应于路径元素的顺序。返回的方法handle 可用于计算类似于byteOffset(PathElement...)
的布局偏移量,但仅在调用方法句柄时指定一些序列索引。方法句柄返回的最终偏移量计算如下:
bitOffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n) offset = bitOffset / 8
x_1
、x_2
、...x_n
是作为long
参数提供的 dynamic 值,而c_1
、c_2
、 ...c_m
是 static 偏移常量和s_0
,s_1
, ...s_n
是 static 步幅常数,它们源自布局路径.如果计算的位偏移量不是 8 的倍数,则方法句柄将抛出
UnsupportedOperationException
。- 参数:
elements
- 布局路径元素。- 返回:
- 一个方法句柄,可用于计算给定布局路径元素指定的布局元素的字节偏移量,当提供缺少的序列元素索引时。
- 抛出:
IllegalArgumentException
- 如果布局路径包含一个或多个选择多个序列元素索引的路径元素(请参阅MemoryLayout.PathElement.sequenceElement(long, long)
)。UnsupportedOperationException
- 如果布局路径遍历的布局之一具有未指定的大小。
-
varHandle
创建一个内存访问变量句柄,可用于在给定布局路径选择的布局中取消引用内存,其中该路径被认为植根于此布局。返回的内存访问变量句柄访问的最终内存位置可以计算如下:
address = base + offset
base
表示由MemorySegment
访问坐标表示的基地址(参见MemorySegment.address()
和MemoryAddress.toRawLongValue()
),offset
可以用以下形式表示:offset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
x_1
、x_2
、...x_n
是作为long
参数提供的 dynamic 值,而c_1
、c_2
、 ...c_m
是 static 偏移常量和s_0
,s_1
, ...s_n
是 static 步幅常数,它们源自布局路径.- API 注意:
-
生成的 var 句柄将为该布局路径中包含的每个未指定的序列访问组件提供一个额外的
long
访问坐标。此外,生成的 var 句柄具有某些 访问模式限制 特征,这是所有内存访问 var 句柄所共有的。 - 参数:
carrier
- var 句柄载体类型。elements
- 布局路径元素。- 返回:
-
一个 var 句柄,可用于在
elements
中的布局路径选择的(可能是嵌套的)布局处取消引用内存。 - 抛出:
UnsupportedOperationException
- 如果布局路径具有一个或多个具有不兼容对齐约束的元素,或者如果布局路径遍历的布局之一具有未指定的大小。IllegalArgumentException
- 如果载体不代表基本类型,如果载体是void
、boolean
,或者如果elements
中的布局路径没有选择值布局(请参阅ValueLayout
),或者如果所选值布局的大小符合与指定的运营商类型不匹配。
-
sliceHandle
创建一个方法句柄,给定内存段,该方法句柄返回与给定布局路径选择的布局相对应的slice,其中该路径被视为以此布局为根。返回的方法句柄的返回类型为
MemorySegment
,具有MemorySegment
参数作为表示要切片的段的前导参数,并且具有与提供的布局路径中的自由维度一样多的尾随long
参数类型(请参阅MemoryLayout.PathElement.sequenceElement()
,其中顺序参数的顺序对应于路径元素的顺序。返回的方法句柄可用于创建类似于使用MemorySegment.asSlice(long, long)
的切片,但其中偏移参数是根据调用方法句柄时指定的索引动态计算的。返回段的偏移量计算如下:
bitOffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n) offset = bitOffset / 8
x_1
、x_2
、...x_n
是作为long
参数提供的 dynamic 值,而c_1
、c_2
、 ...c_m
是 static 偏移常量和s_0
,s_1
, ...s_n
是 static 步幅常数,它们源自布局路径.计算偏移量后,返回的段就好像通过调用创建:
segment.asSlice(offset, layout.byteSize());
segment
是要切片的段,其中layout
是给定布局路径选择的布局,根据select(PathElement...)
。如果计算的位偏移量不是 8 的倍数,则方法句柄将抛出
UnsupportedOperationException
。- 参数:
elements
- 布局路径元素。- 返回:
- 一个方法句柄,可用于在给定段的情况下创建所选布局元素的切片。
- 抛出:
UnsupportedOperationException
- 如果所选布局的大小(以位为单位)不是 8 的倍数。
-
select
从以该布局为根的路径中选择布局。- 参数:
elements
- 布局路径元素。- 返回:
-
由
elements
中的布局路径选择的布局。 - 抛出:
IllegalArgumentException
- 如果布局路径未选择嵌套在此布局中的任何布局,或者布局路径包含选择一个或多个序列元素索引的一个或多个路径元素(请参阅MemoryLayout.PathElement.sequenceElement(long)
和MemoryLayout.PathElement.sequenceElement(long, long)
)。
-
map
创建此布局的转换副本,其中从以该布局为根的路径中选择的布局被替换为应用给定操作的结果。- 参数:
op
- 要应用于所选布局的一元运算。elements
- 布局路径元素。- 返回:
-
新布局,其中
elements
中的布局路径选择的布局已被将op
应用到所选布局的结果替换。 - 抛出:
IllegalArgumentException
- 如果布局路径未选择嵌套在此布局中的任何布局,或者布局路径包含选择一个或多个序列元素索引的一个或多个路径元素(请参阅MemoryLayout.PathElement.sequenceElement(long)
和MemoryLayout.PathElement.sequenceElement(long, long)
)。
-
isPadding
boolean isPadding()这是一个填充布局(例如从paddingLayout(long)
创建的布局)吗?- 返回:
- true,如果此布局是填充布局。
-
equals
比较指定对象与此布局是否相等。当且仅当指定对象也是一个布局,并且它等于此布局时,才返回true
。如果两个布局属于同一类型、具有相同的大小、名称和对齐约束,则它们被视为相等。此外,根据布局类型,必须满足附加条件:- 如果两个值布局具有相同的字节顺序,则它们被视为相等(请参阅
ValueLayout.order()
) - 如果两个序列布局具有相同的元素计数(请参阅
SequenceLayout.elementCount()
),并且它们的元素布局(请参阅SequenceLayout.elementLayout()
)也相等,则认为它们相等 - 如果两个组布局属于同一类型(请参阅
GroupLayout.isStruct()
、GroupLayout.isUnion()
)并且它们的成布局(请参阅GroupLayout.memberLayouts()
)也相等,则认为它们相等
- 如果两个值布局具有相同的字节顺序,则它们被视为相等(请参阅
-
hashCode
int hashCode()返回此布局的哈希码值。 -
toString
String toString()返回此布局的字符串表示形式。 -
paddingLayout
创建具有给定大小的新填充布局。- 参数:
size
- 以位为单位的填充大小。- 返回:
- 新的选择器布局。
- 抛出:
IllegalArgumentException
- 如果size <= 0
。
-
valueLayout
创建给定字节顺序和大小的值布局。- 参数:
size
- 值布局大小。order
- 值布局的字节顺序。- 返回:
- 新的值布局。
- 抛出:
IllegalArgumentException
- 如果size <= 0
。
-
sequenceLayout
使用给定的元素布局和元素计数创建新的序列布局。- 参数:
elementCount
- 序列元素计数。elementLayout
- 序列元素布局。- 返回:
- 具有给定元素布局和大小的新序列布局。
- 抛出:
IllegalArgumentException
- 如果elementCount < 0
。
-
sequenceLayout
创建一个新的序列布局,具有无限的元素计数和给定的元素布局。- 参数:
elementLayout
- 序列布局的元素布局。- 返回:
- 具有给定元素布局的新序列布局。
-
structLayout
使用给定的成布局创建新的struct组布局。- 参数:
elements
- struct 组布局的成布局。- 返回:
- 具有给定成布局的新struct组布局。
-
unionLayout
使用给定的成布局创建新的union组布局。- 参数:
elements
- union 布局的成布局。- 返回:
- 具有给定成布局的新union组布局。
-