2015-05-05 5 views
10

У меня есть функция C сопоставлен Swift определяется как:Swift строки новообращенного UnsafeMutablePointer <Int8>

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) 

но линия путь [я] я получаю сообщение об ошибке:

'subscript' is unavailable: cannot subscript String with a range of Int

swe_set_ephe_path(NSBundle.mainBundle().bundlePath) 

ни

swe_set_ephe_path(&NSBundle.mainBundle().bundlePath) 

не работает либо

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

+0

Пожалуйста, при отображении кода, всегда показывать _real_ код. Ваше заявление не является реальным - это не действительное объявление функции Swift, и я подозреваю, что имя функции неверно. Не вводите код в Stack Overflow; скопируйте и вставьте код _real_. Всегда. – matt

ответ

15

Previous answers on StackOverflow using CString don't seem to work anymore

Тем не менее, 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, но он отлично работает в моем тестировании, когда он потушил так:

+0

Это, казалось, отлично работает. Он использует аспекты Swift, с которыми я не знаком, поэтому для ответа на вопрос и урок по более продвинутым языковым аспектам он является победителем в обоих пунктах. Благодаря! – SteveFerg

+0

Восторг, чтобы помочь. Все это вышло из моей книги, здесь: http://www.apeth.com/swiftBook/apa.html#_c_data_types. Сообщите мне, что у вас есть дополнительные вопросы о том, что делает код. – matt

+0

Черт! Я только что купил и прочитал эту книгу, но не смотрел приложение! Я сейчас ... – SteveFerg

6

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

Если это не так, то функция будет приходить к Свифту как:

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

и вы могли бы полагаться на неявном преобразовании Свифта:

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)) 
} 
+0

Да, я думал показать ему 'withCString' как альтернативу Swiftier для' (s как NSString) .UTF8String' - я на самом деле положил это, а потом снова взял его. :) - Я понятия не имею, зачем ему нужен небезопасный изменяемый указатель; Я просто дал ему один, потому что он сказал, что он нужен. – matt

+0

Помимо чистоты - Быстрота, я предпочитаю 'withCString', поскольку он явно указывает область видимости. Я очень нервничаю по поводу этого '(str как NSString) .UTF8String'. Когда эта версия 'NSString' будет уничтожена, предположительно, взяв память, выделенную для нее версией UTF-8? Не ясно. Возможно, прежде чем вы получите возможность использовать его ... –

+0

На самом деле он никогда не выделялся. Это всего лишь способ взглянуть на исходную строку. Я доверяю компилятору не оптимизировать исходную строку! Может быть, я не должен. – matt

5

Я имел статическая библиотека (someLibrary.a), написанная на C++, скомпилированная для 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)

Смежные вопросы