Передача быстрой строки в функцию c char * - PullRequest
0 голосов
/ 10 мая 2019

Я пытаюсь передать строковый аргумент из оболочки функции swift в функцию C, которая принимает char *.

Эта функция ac

long swe_fixstar2_ut(char* star, double tjd_ut, long iflag, double* xx, char* serr);

Параметр star должен содержать не менее 41символы для возвращенного имени звезды.Если звезда найдена, ее имя возвращается.Эта функция ищет имя звезды из текстового файла.

При импорте в 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)
}

Я просмотрел несколько похожих вопросов, но это не решило мою проблему.

Преобразование Swift Array of String в a в указатель массива C-строк

Как передать массив строк Swift в функцию C с помощью параметра char **

На самом деле эта функция взята из швейцарской эфемеридной библиотеки C.Вот ссылка, если вам, ребята, интересно посмотреть

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

1 Ответ

2 голосов
/ 10 мая 2019

Насколько я прочитал документ, параметр star используется как для входа, так и для выхода, поэтому star функции Swift должно быть inout.

И longимпортируется как Int, и на 64-разрядных платформах Apple он представляет 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-функцию, когда функцияне сохраняет указатели для последующего использования.С использованием массивов вам не нужно беспокоиться об освобождении.

Вы можете видеть, как код преобразует входные данные star в массив CChar и скрывает массив в строку.

Если вы нашли что-то не так с этим кодом, пожалуйста, сообщите мне.

...