Создайте строковый буфер в Swift для C, чтобы использовать и освободить позже - PullRequest
1 голос
/ 01 мая 2019

Быстрая форма вопроса для тех, кто знает Rust: есть ли в Swift 5 эквивалент std::ffi::CString, который может владеть строкой и превратить ее в char* как into_raw и позже освободите / удалите его, используя что-то вроде from_raw ?

Более длинная версия:

У меня есть C API, который я использую в Swift. Я должен предоставить функцию обратного вызова, которую я предоставляю в качестве аргумента закрытия, и это закрытие должно возвращать строку с нулевым символом в конце как const char * - в Swift это типизируется как UnsafePointer<Int8>?.

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

Какой наименее болезненный способ выделить некоторую память в Swift, инициализированную строкой UTF-8, предоставить const char * для C, а затем освободить его позже, когда будет дано указание?

1 Ответ

3 голосов
/ 01 мая 2019

Два возможных варианта:

let swiftString = "Hello world"
swiftString.withCString { cStringPtr in
    // use `cStringPtr` ...

}

вызывает замыкание с указателем как строковое представление C строки Swift (в кодировке UTF-8). Этот указатель действителен только во время выполнения замыкания.

Для увеличения срока службы вы можете сделать

let swiftString = "Hello world"
let cStringPtr = strdup(swiftString)
// use `cStringPtr` ...

, который выделяет новую строку C из заданной строки Swift и освобождает эту память позже с помощью

free(cStringPtr)
...