Swift 结构外部填充

标签 swift xcode llvm

所以我在 swift 中有以下结构

typealias float = Float32
typealias Point = float2
typealias Int = UInt32

//This is a struct that is meant to be the elements in an array that is immensly acessable to c
//CAREFUL this is LIKELY mirrored in a different thing
public struct Info {
    var position:Point = Point(x: 0, y: 0)
    var strength:float = 1
    var altitude:float = 3.141592 / 2.0
    var azmuth:Point = Point(x: 0, y: 0)
    var state:Int = 0
}

此结构存储在使用 Array(repeating: ...

分配的数组内

每一帧我都会将一个指向该数组的指针传递到我的 C++ 代码中,这里我有一个镜像结构

struct Info {
    float positionX;
    float positionY;
    float strength;
    float altitude;
    float azmuthX;
    float azmuthY;
    int state;
    float pad; //WHy???
}; 

现在请注意它在那里的额外 float “pad”,因为在结构声明中没有它,当我去读取第一个元素以外的元素时,数据会偏移一个 float 的大小(事物将被移动一个字段)结束)。

为什么 C++ 结构上的 pad 字段是必需的? Swift 中额外的 float 或额外填充的原因是什么?

最佳答案

float2是 C 类型 simd_float2 的 Swift 映射,即 定义于 <simd/vector_types.h作为

/*! @abstract A vector of two 32-bit floating-point numbers.
 *  @description In C++ and Metal, this type is also available as
 *  simd::float2. The alignment of this type is greater than the alignment
 *  of float; if you need to operate on data buffers that may not be
 *  suitably aligned, you should access them using simd_packed_float2
 *  instead.                                                                  */
typedef __attribute__((__ext_vector_type__(2))) float simd_float2;

重点是

The alignment of this type is greater than the alignment of float

您可以通过以下方式验证这一点

print(MemoryLayout<float>.alignment)  // 4
print(MemoryLayout<float2>.alignment) // 8

这会导致 Swift 类型 Info对齐到 8,及其步幅(即偏移量 连续 Info 之间的字节数存储在数组中的元素)为 32。

print(MemoryLayout<Info>.alignment) // 8
print(MemoryLayout<Info>.stride)    // 32

另一方面,C型struct Info只有floatint 成员,它们都具有 4 字节对齐。如果没有 最终float pad;成员,数组中该类型的连续元素之间的偏移量是 28 字节,而不是 32。

这就解释了其中的区别。你真正应该做的是定义 仅 C 中的类型,并将该定义导入到 Swift 中。这是 保证保留内存布局的唯一方法, 正如苹果公司的乔·格罗夫(Joe Groff)在 Mapping C semantics to Swift :

If you depend on a specific layout, you should define the struct in C and import it into Swift for now.

关于Swift 结构外部填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49716569/

相关文章:

c++ - LTO 与 LLVM 和 CMake

haskell - 将 G-Machine 源转换为 LLVM IR

iOS swift : Best practices for starting app with an alternative UIViewController

swift - Label 和 ProgressBar 不会更新 macOS Swift

objective-c - UIActivityType – 属性不能是@objc 覆盖,因为它的类型不能在 Objective-C 中表示

swift - 是否可以快速覆盖 find(sequence, element) 函数?

ios - 断点调试器命令中的po $ arg1和bt之间有区别吗?

c++ - LLVM 是否有用于消除 Microsoft C++ 损坏的工具?

iphone - UIView 控件在动画完成之前不绘制

ios - 视频在 xcode 模拟器上播放但不在设备上播放