Возможное решение:
withUnsafeMutablePointer(&myVarOfStructProduct.name) {
strlcpy(UnsafeMutablePointer($0), productName, UInt(sizeofValue(myVarOfStructProduct.name)))
}
Внутри блока, $0
является (изменяемый) указатель на кортеж. Этот указатель преобразован в UnsafeMutablePointer<Int8>
, как ожидалось, BSD library function strlcpy()
.
Он также использует тот факт, что Swift строка productName
является автоматически к UnsafePointer<UInt8>
, как описано в String value to UnsafePointer<UInt8> function parameter behavior. Как упоминалось в комментариях в этом потоке , это делается путем создания временного массива UInt8
(или последовательности?). Так альтернативно можно перечислить UTF-8 байт в явном виде и поместить их в пункт назначения:
withUnsafeMutablePointer(&myVarOfStructProduct.name) {
tuplePtr -> Void in
var uint8Ptr = UnsafeMutablePointer<UInt8>(tuplePtr)
let size = sizeofValue(myVarOfStructProduct.name)
var idx = 0
if size == 0 { return } // C array has zero length.
for u in productName.utf8 {
if idx == size - 1 { break }
uint8Ptr[idx++] = u
}
uint8Ptr[idx] = 0 // NUL-terminate the C string in the array.
}
Еще одно возможное решение (с промежуточным NSData
объекта):
withUnsafeMutablePointer(&myVarOfStructProduct.name) {
tuplePtr -> Void in
let tmp = productName + String(UnicodeScalar(0)) // Add NUL-termination
let data = tmp.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!
data.getBytes(tuplePtr, length: sizeofValue(myVarOfStructProduct.name))
}
Обновление для Swift 3:
withUnsafeMutablePointer(to: &myVarOfStructProduct.name) {
$0.withMemoryRebound(to: Int8.self, capacity: MemoryLayout.size(ofValue: myVarOfStructProduct.name)) {
_ = strlcpy($0, productName, MemoryLayout.size(ofValue: myVarOfStructProduct.name))
}
}
Это смешно, потому что у меня была [противоположная проблема] (http://stackoverflow.com/questions/27455773/converting-a-c-char-array-to-a-string). – zneak