【发布时间】:2015-07-20 17:45:05
【问题描述】:
我正在尝试将结构数组从 c++ 代码返回到 swift 代码。
Swift 代码:
struct CPoint {
let x: CDouble
let y: CDouble
}
struct CStruct {
let p1: CPoint
let d: CDouble
let p2: CPoint
let i: CInt
}
func get_structs() {
let cnt = ... //Getting size from c++ code
var buf = [CStruct](count: cnt, repeatedValue: CStruct(p1: CPoint(x: 0, y: 0), d: 0, p2: CPoint(x: 0, y: 0), i: 0))
let addr = UnsafeMutableBufferPointer(start: &buf, count: buf.count).baseAddress
get_structs_c(addr)
for cstruct in buf {
//First cstruct is OK. Next are corrupted.
}
}
C++ 代码:
typedef struct Point {
double x;
double y;
}
typedef struct Struct {
Point p1;
double d;
Point p2;
int i;
}
void get_structs_c(void *buf) {
Struct * structs = (Struct *) buf;
const std::vector<const Struct *> vec = ... // getting values no matter from where
for (int i = 0; i < vec.size(); i++) {
const Struct * s = vec.at(i);
structs[i] = Struct{ s->p1, s->d, s->p2, s->i};
}
}
代码很简单,但结果损坏的值会保存到buf。
但是,如果我从CStruct 和Struct 中删除i 字段,那么它将返回正确的值,或者如果我将i 的类型从CInt 和int 更改为CDouble 和Double,然后也会返回正确的值。因此,int 桥接可能存在一些问题。
我检查了 CStruct 和 Struct 的大小,它似乎是相同的 44 个字节。
任何帮助表示赞赏,在此先感谢!
UPD 1:只有当结构的大小与 8 个字节成正比时才能正常工作。
UPD 2:我检查了内存寻址,发现 swift 的 sizeof 表明了这一点
struct CStruct {
let p1: CPoint
let d: CDouble
let p2: CPoint
let i: CInt
}
大小为 44 字节,但是 &struct[1] - &struct[0] = 48!
如果以更糟糕的方式重新排序结构字段:
struct CStruct {
let i: CInt
let p1: CPoint
let d: CDouble
let p2: CPoint
}
然后它会自动对齐,sizeof 给出 48 的大小并且它可以正常工作。
这样的默认不兼容正常吗?
【问题讨论】: