将 swift 字符串传递给 c 函数 char *

Passing swift string to c function char *

我正在尝试将字符串参数从 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)
}

我看了几个类似的问题,但它并没有解决我的问题。

其实这个函数来自瑞士星历C库。这里是link有兴趣的可以看看

https://www.astro.com/swisseph/swephprg.htm#_Toc505244846

据我阅读文档,参数 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)
}

当函数不保留指针供以后使用时,我更喜欢在将指针传递给 C-function 时使用数组。使用数组,您无需担心释放问题。

您可以看到代码如何将输入 star 转换为 CChar 数组并将数组转换回字符串。

如果您发现此代码有问题,请告诉我。