我有一个看起来像这样的C API:
typedef struct Datapoints {
double *ptr;
uintptr_t len;
} Datapoints;
double my_function(const struct Datapoints *baseline_data,
uint32_t baseline_data_len,
const struct Datapoints *new_data);
我发现从Swift调用此函数很困难。第一个参数是指向Datapoints
结构体的指针数组,第三个参数是单个Datapoints
结构体。
这是我想到的方法,但由于多种原因它无法工作,主要原因是我试图存储一系列不安全的指针以便稍后将它们传递给my_function
。我已经通过重命名变量和类型来混淆代码,如果它不能编译,请原谅我。代码基本上看起来像这样:
var baseline_datapoints = [Datapoints]()
var current_datapoints:Datapoints = Datapoints()
// This loop was intended to build up an array `baseline_Datapoints` containing pointers to struct `Datapoints`
for reading in baseline {
let datapoints:[Double] = reading.datapoints
// Won't work: The pointer passed as an argument to `body` is valid only during the
// execution of `withUnsafeMutableBufferPointer(_:)`. Do not store or return
// the pointer for later use.
// We _are_ attempting to store it for later use.
datapoints.withUnsafeMutableBufferPointer{ ptr in
baseline_datapoints.append(Datapoints(ptr: ptr.baseAddress, len: UInt(datapoints.count)) )
}
}
self.newData.withUnsafeMutableBufferPointer {ptr in
current_datapoints = Datapoints(ptr: ptr.baseAddress, len: UInt(self.newData.count))
}
let x = baseline_datapoints.withUnsafeBufferPointer{
(baselineptr: UnsafeBufferPointer<Datapoints>) -> Double in
return withUnsafePointer(to: current_datapoints) {
(current_ptr: UnsafePointer<Datapoints>) -> Double in
return my_function(baseline_ptr.baseAddress, UInt32(baseline_datapoints.count ), current_ptr)
}
}
我认为我应该扩展withUnsafeXxxPointer
闭包的范围,以便数据保持足够长的有效期。然而,在尝试构建baseline_data
列表时如何做我并不确定。
此外,对于每个不安全指针使用一个闭包似乎很不方便。如果我那样做,它将导致代码嵌套深度增加。有其他方法吗?
欢迎任何建议。
编辑:
接受的答案完美地解决了问题,只是第三个参数是按值传递的。 然而,这对于 C API 来说实际上是更好的设计,所以我将我的 API 更改为如下:
double my_function(const struct Datapoints *baseline_data,
uint32_t baseline_data_len,
const struct Datapoints new_data);
这里记录了输入的两个参数baseline_data
和new_data
。
new_data
现在通过值传递。你说得对,这是不明确的。 - pnadeau