Swift конвертировать строку в UnsafeMutablePointer <Int8>

У меня есть функция C, отображаемая в Swift, определенная как:

func swe_set_eph_path(path: UnsafeMutablePointer<Int8>) -> Void

Я пытаюсь передать путь к функции и попытался:

        var path = [Int8](count: 1024, repeatedValue: 0);
        for i in 0...NSBundle.mainBundle().bundlePath.lengthOfBytesUsingEncoding(NSUTF16StringEncoding)-1
        {
            var range = i..<i+1
            path[i] = String.toInt(NSBundle.mainBundle().bundlePath[range])
        }
        println("\(path)")
        swe_set_ephe_path(&path)

но на пути [i] я получаю ошибку:

"индекс" недоступен: не может содержать индекс String с диапазоном Int

swe_set_ephe_path(NSBundle.mainBundle().bundlePath)

ни

swe_set_ephe_path(&NSBundle.mainBundle().bundlePath)

тоже не работают

Помимо того, что я не работаю, я чувствую, что это должен быть лучший, менее запутанный способ сделать это. Предыдущие ответы на StackOverflow с использованием CString больше не работают. Любые предложения?

Ответ 1

Предыдущие ответы на StackOverflow с использованием CString больше не работают

Тем не менее, UnsafePointer<Int8> является строкой C. Если ваш контекст абсолютно необходим UnsafeMutablePointer, просто принудите, например:

let s = NSBundle.mainBundle().bundlePath
let cs = (s as NSString).UTF8String
var buffer = UnsafeMutablePointer<Int8>(cs)
swe_set_ephe_path(buffer)

Конечно, у меня нет вашего swe_set_ephe_path, но он отлично работает в моем тестировании, когда он заштрихован вот так:

func swe_set_ephe_path(path: UnsafeMutablePointer<Int8>) {
    println(String.fromCString(path))
}

Ответ 2

Фактически это крайне раздражает используемую вами библиотеку, которая требует (в декларации C) char * path, а не const char * path. (это предполагает, что функция не мутирует входную строку - если это так, вы в совершенно другой ситуации).

Если это не так, функция перейдет к Swift как:

// note, UnsafePointer not UnsafeMutablePointer
func swe_set_eph_path(path: UnsafePointer<Int8>) -> Void

и тогда вы можете полагаться на неявное преобразование Swifts:

let str = "blah"
swe_set_eph_path(str) // Swift implicitly converts Strings 
                      // to const C strings when calling C funcs

Но вы можете легко выполнить небезопасное преобразование в сочетании с функцией withCString:

str.withCString { cstr in
    swe_set_eph_path(UnsafeMutablePointer(cstr))
}

Ответ 3

У меня была статическая библиотека (someLibrary.a), написанная на С++, скомпилированная для iOS. Файл заголовка (someLibrary.h) имел функцию, открытую следующим образом:

extern long someFunction(char* aString);

Объявление в Swift выглядит следующим образом:

Int someFunction(aString: UnsafeMutablePointer<Int8>)

Я сделал расширение до String:

extension String {
    var UTF8CString: UnsafeMutablePointer<Int8> {
        return UnsafeMutablePointer((self as NSString).UTF8String)
    }
}

Итак, я могу вызвать метод следующим образом:

someFunction(mySwiftString.UTF8CString)