我正在使用我的Swift代码中的C函数来输出数组。该函数不返回数组,因为显然在C语言中,不鼓励函数返回数组。因此,该函数采用in-out
参数(作为指针)并将数组放置在那里。
C函数:
void kRing(H3Index origin, int k, H3Index* out);
H3Index*
是采用数组的out
参数。但是,如何在Swift中从此函数获取数组? H3Index*
(out
参数)指向一个整数。而且,显然在C语言中,您可以指向整数,将该指针传递给函数,并且该函数可以将数组放置在该指针的位置(即使它指向整数)。
但是由于Swift的类型安全性,因此很难从函数中获取数组。 Swift版本:
kRing(origin: H3Index, k: Int32, out: UnsafeMutablePointer<H3Index>!)
我的Swift实现:
let h3Index: H3Index = 600022775385554943 // integer
let k: Int32 = 2 // integer
var result = H3Index() // the in-out parameter (must be integer to satisfy Swift's type safety)
_ = withUnsafeMutablePointer(to: &result) { kRing(h3Index, k, $0) }
print(result)
并且它显示结果(访问错误,我现在不在乎)。但是当它应该是数组时,结果是一个整数。如何完成?
C实现,以供参考:
H3Index indexed = 0x8a2a1072b59ffffL; // 64-integer (hex)
int k = 2; // integer
int maxNeighboring = maxKringSize(k); // integer
H3Index* neighboring = calloc(maxNeighboring, sizeof(H3Index)); // the out parameter (a pointer to an integer and/or array)
kRing(indexed, k, neighboring); // the function
for (int i = 0; i < maxNeighboring; i++) {
if (neighboring[i] != 0) {
// iterate through array
}
}
在C中,
H3Index* neighboring = calloc(maxNeighboring, sizeof(H3Index));
kRing(indexed, k, neighboring);
为类型为maxNeighboring
的H3Index
个元素分配内存,并将内存初始化为零。然后将该存储块的地址(即第一个元素的地址)传递给kRing
函数。
可以从Swift调用calloc
和free
,但更易于使用的API是Unsafe(Mutable)(Buffer)Pointer
及其allocate()
和deallocate()
方法:let neighboring = UnsafeMutableBufferPointer<H3Index>.allocate(capacity: maxNeighboring)
neighboring.initialize(repeating: 0)
kRing(indexed, k, neighboring.baseAddress)
现在您可以使用以下命令打印值
for i in 0..<maxNeighboring { print(neighboring[i]) }
或更简单
for neighbor in neighboring { print(neighbor) }
因为。最终,您必须释放内存以避免内存泄漏:Unsafe(Mutable)BufferPointer
是可以迭代的集合
neighboring.deallocate()
一种替代方法是使用定义Swift并将元素存储的地址传递给C函数:array,
var neighboring = Array<H3Index>(repeating: 0, count: maxNeighboring)
kRing(indexed, k, &neighboring)
for neighbor in neighboring { print(neighbor) }
[neighboring
现在是局部变量,因此内存会自动释放。