所以我在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???
};
现在注意它在那里的额外的浮点“pad”,因为当我去读取第一个元素以外的元素时,没有它在结构声明中,数据被一个float的大小偏移(事物将被移动一个字段结束)。
为什么c ++结构上的pad字段是必需的? Swift中额外填充的额外浮动或原因是什么?
答案 0 :(得分:2)
ConfigFileReader.Java17: FileInputStream fis = new FileInputStream(propertyFilePath);
EndtoEndTest.java32:cnffilered = new ConfigFileReader();
是C类型float2
的Swift映射,它是
在simd_float2
中定义为
<simd/vector_types.h
关键点是
此类型的对齐方式大于float
的对齐方式
您可以使用
验证/*! @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;
这会导致Swift类型print(MemoryLayout<float>.alignment) // 4
print(MemoryLayout<float2>.alignment) // 8
的对齐为8,其步幅(即偏移量)
以字节为单位存储在数组中的连续Info
元素之间的字节数为32。
Info
另一方面,C类型print(MemoryLayout<Info>.alignment) // 8
print(MemoryLayout<Info>.stride) // 32
只有struct Info
和float
成员,都具有4个字节的对齐。没有
final int
成员,数组中此类型的连续元素之间的偏移量为28个字节,而不是32个。
这解释了差异。你实际应该做的是定义
仅限C类型,并将该定义导入Swift。这是
保证保留内存布局的唯一方法,
正如Apple的Joe Groff所写
multiprocessing
:
如果您依赖于特定的布局,则应该在C中定义结构并将其导入到Swift中。