【发布时间】:2016-07-12 13:00:38
【问题描述】:
我正在编写一个 C 数学库的包装器。每个函数都接受一个或两个函数作为参数。但是,这些子函数(以及父函数)的参数不是 Swifty - 因此是包装器。
我已经清理了示例代码以仅显示三个主要部分:c-library 函数,将传递给包装器的所需 Swift 函数(主体未显示,但包装 c-library 函数) ,以及所需的C函数形式。
//C library function, that calls the passed function dozens, hundreds or thousands of times, each time it changes the data provided in p, and uses the output from x
//The Swift arrays are passed as pointers, and the length of the and x array are m and n respectively
returnValue = cLibraryFunc(passedFunc, &p, &x, Int32(m), Int32(n), Int32(itmax), &opts, &info, &work, &covar, &adata)
//I would like to create a Swift function that would look like this (internals could be any myriad of things that takes inputs p and adata and returns data in x:
func desiredSwifty(p: inout [Double], x: inout [Double], m: Int, n: Int, adata: inout [Double]) {
//very simple example
//this example knows the length of p (so m as well)
//and assumes that adata length is the same as the x length (n)
//obviously, it could ifer m and n from p.count and x.count
for i in 0..<n {
x[i] = p[0] + p[1]*adata[i] + p[2]*pow(adata[i], 2)
}
}
//And the wrapper would "convert" it -internally- into the form that the C library function requires:
func requiredC(p: UnsafeMutablePointer<Double>?, x: UnsafeMutablePointer<Double>?, m: Int32, n: Int32, adata: UnsafeMutablePointer<Void>?) {
//same thing, but using pointers, and uglier
//first, have to bitcast the void back to a double
let adataDouble : UnsafeMutablePointer<Double> = unsafeBitCast(adata, to: UnsafeMutablePointer<Double>.self)
for i in 0..<Int(n) {
x![i] = p![0] + p![1]*adataDouble[i] + p![2]*pow(adataDouble[i], 2)
}
}
加法
我应该补充一点,我可以访问 c 源代码,所以我可能会添加一些虚拟参数(可能是为了找到传递上下文的方法)。但是鉴于文档似乎表明无法使用 c 函数指针获取上下文,这可能没有用。
【问题讨论】:
-
可怜的人将维护该代码。 (我将此类代码称为“单向/一次性代码”。)
-
我已经对 C 库进行了一些测试,并且由于它有很好的文档记录并被其他人使用,我对当前版本感到安全。但是,我只打算为自己使用这个包装器。我只是想隐藏C的“丑陋”。
-
我没有评论内容,只是评论了编码风格。大量缩进的部分在任何 PL 中都不能被认真对待。
-
我很想知道如何在没有嵌套
withUnsafeMutableBufferPointers 的疯狂树的情况下使用这些指针。我发现的唯一“解决方案”是为该树编写一个包装器(这意味着它仍然存在于某处)。
标签: c swift wrapper unsafemutablepointer