我试图将字符串参数从swift函数包装器传递给采用char *的C函数。
这是一个c函数
long swe_fixstar2_ut(char* star, double tjd_ut, long iflag, double* xx, char* serr);
参数star必须至少提供41个字符作为返回的星形名称。如果找到星星,则返回其名称。此功能从txt文件中搜索星级名称。
当导入到Swift函数时,看起来像这样
swe_fixstar_ut(star: UnsafeMutablePointer<Int8>!, tjd_ut: Double, iflag: int32,
xx: UnsafeMutablePointer<Double>!, serr: UnsafeMutablePointer<Int8>!)
我想实现这样的目标
public func sweFixStarsUT(star: String, tjdUT: Double, iFlag: Int32) {
let xx: UnsafeMutablePointer = UnsafeMutablePointer<Double>.allocate(capacity:6)
let serr:UnsafeMutablePointer = UnsafeMutablePointer<CChar>.allocate(capacity:256)
swe_fixstar_ut(star, tjdUT, iFlag, xx, serr)
}
我环顾了几个类似的问题,但这并不能解决我的问题。
Convert a Swift Array of String to a to a C string array pointer
How to pass an array of Swift strings to a C function taking a char ** parameter
实际上,此功能来自瑞士星历C库。如果您有兴趣看的话,这里是链接
答案 0 :(得分:2)
据我阅读文档,参数star
用于输入和输出,因此您的Swift函数的star
应该是inout
。
然后将long
导入为Int
,并且在Apple的64位平台中,它表示64位有符号整数类型,如果实际上是32位,则可能需要更新源您的C代码文件。我认为它是Int
。
因此,我将这样编写桥接代码:
public func sweFixStarsUT(star: inout String, tjdUT: Double, iFlag: Int) {
let starLen = max(star.utf8.count, 41)
var starBuf: [CChar] = Array(repeating: 0, count: starLen+1)
strcpy(&starBuf, star)
var xx: [Double] = Array(repeating: 0.0, count: 6)
var serr: [CChar] = Array(repeating: 0, count: 256)
swe_fixstar2_ut(&starBuf, tjdUT, iFlag, &xx, &serr)
star = String(cString: starBuf)
}
当函数的指针不保留指针供以后使用时,我更喜欢使用数组。使用数组,您无需担心分配问题。
您可以看到代码是如何将输入star
转换为CChar数组并将其覆盖回String的。
如果您发现此代码有问题,请告诉我。