C中offsetof(struct,member)的Swift中的等价物是什么?

时间:2018-03-06 01:46:44

标签: swift memory struct offset

这是Swift中的结构:

struct A {
    var x
    var y
    var z
}

我应该如何在结构y中获取A的偏移量,就像在C中的offsetof(A, y)一样?

谢谢:)

3 个答案:

答案 0 :(得分:5)

Swift目前没有为Swift中定义的结构定义标准内存布局。这意味着您编写的任何通过指针数学分解结构的代码都不能保证在Swift编译器的未来版本或更新版本上工作。 (正如@robmayoff所说,这是Swift获得稳定ABI的一部分,这是今年第5版Swift项目的目标之一。)

如果您的结构在C中定义并通过桥接头导入,则Swift会尊重其内存的C二进制布局。在这种情况下,MemoryLayout类型提供C sizeof运算符和类似实用程序的等价物。仍然没有offsetof等价物,但你可以通过在C声明顺序中添加成员类型的stride来自己做指针数学。

例如,SCNGeometrySource的Apple文档有一个从交错的顶点/法线/纹理坐标数据的缓冲区创建3D对象的示例。但它(目前)用ObjC编写,使用sizeofstrideof告诉SceneKit在哪里可以找到缓冲区中的每种数据。 Swift等价物将使用MemoryLayout<Float>.size代替sizeof(float)等,并且代替offsetof(MyVertex, nx)您需要观察在nx之前结构中有三个浮点数。 } field并写MemoryLayout<Float>.stride * 3

答案 1 :(得分:2)

您无法以可靠的方式获得y的偏移量,因为Swift尚不支持该操作。最终,在“ABI稳定性”实施后会有支持。

目前推荐的方法是在C中定义struct,并定义C函数以返回字段的偏移量。

答案 2 :(得分:1)

MemoryLayout.offset(of:) 是在Swift 4.2中添加的,并实现了

示例:

struct A {
    var x: Int8
    var y: Int16
    var z: Int64
}

MemoryLayout.offset(of: \A.x) // 0
MemoryLayout.offset(of: \A.y) // 2
MemoryLayout.offset(of: \A.z) // 8

备注:这也应该工作,但是(从Swift 4.2开始)不能编译(错误SR-8335):

MemoryLayout<A>.offset(of: \.y)
// error: Expression type 'Int?' is ambiguous without more context