Преобразование строки Swift в const char*

Я пытаюсь передать const char * в старую библиотеку C, преобразованную из строки Swift в Swift.

Это функция C, которую я вызываю:

artnet_node artnet_new(const char *ip, int verbose) { ...

как я могу преобразовать строку Swift в этот тип const char? Это работает, когда я передаю ipAddress следующим образом:

internal var ipAddress = "192.168.1.43"

но это не работает, когда я передаю это так

internal var ipAddress:String = "192.168.1.43"

Мне нужно это в функции, где мне нужно указать тип:

internal func setupArtnode(ip:String) -> Int{

Я пытался использовать AnyObject вместо String, но это тоже не работает.

Спасибо.


person Steven B.    schedule 23.12.2016    source источник
comment
Пожалуйста, добавьте разъяснение того, что не работает — компиляция или выполнение, и любые связанные сообщения об ошибках.   -  person sbooth    schedule 24.12.2016


Ответы (4)


Вы должны иметь возможность передать String непосредственно функции C, ожидающей const char *, и она будет автоматически преобразована в строку UTF-8 с завершающим нулем:

let string = "string"
let node = artnet_new(string, 1)

Дополнительную информацию см. в разделе Взаимодействие с C API . Вот соответствующий отрывок:

Когда функция объявлена ​​как принимающая аргумент UnsafePointer, она может принимать любое из следующего:

  • Строковое значение, если Type имеет значение Int8 или UInt8. Строка будет автоматически преобразована в UTF8 в буфере, и указатель на этот буфер будет передан функции.
person sbooth    schedule 23.12.2016
comment
по какой-то причине функция не принимает аргумент и принимает значение по умолчанию, я обновил вопрос, добавив дополнительную информацию - person Steven B.; 24.12.2016
comment
ваша цитата заставила меня использовать UnsafePointer‹Int8›, который, похоже, работал, я добавил свой рабочий код. спасибо!! - person Steven B.; 28.12.2016

Не уверен, почему, но этот код работает. Это передает строку функции C, ожидающей const char*, которая кажется такой же, как unsafePointer.

internal func setupArtnode(ipAddress:String) -> NSInteger{
    let cString = self.ipAddress.cString(using: String.defaultCStringEncoding)!
    let newString:String = NSString(bytes: cString, length: Int(ipAddress.characters.count), encoding:String.Encoding.ascii.rawValue)! as String
    let key2Pointer = UnsafePointer<Int8>(newString)

    node = artnet_new(key2Pointer, Int32(verbose))     // VERBOSE : true(1) , false(0)
...
person Steven B.    schedule 28.12.2016

Простой способ для Swift 3

var ipAddress: String = "192.168.1.43"
var verbose: Int = 1
artnet_node artnet_new((ipAddress as NSString).utf8String, verbose)
person Cao Mạnh Quang    schedule 20.04.2018
comment
При использовании sqlite3 API sqlite3_bind_text() с swift я наблюдал повреждение памяти и странные результаты, если строка была передана напрямую. (ipAddress as NSString).utf8String исправил это. - person vine'th; 30.10.2018

Вы не указали, что содержит ваш массив Swift. В любом случае вам нужно преобразовать массив Swift в массив Int8:

let str = "Hello world"
let cArray = str.cString(using: .utf8)

artnet_new(cArray, 1)
person Code Different    schedule 23.12.2016
comment
Извините, я опечатался, я пытаюсь изменить одну строку на const char: s, отредактировал вопрос - person Steven B.; 24.12.2016