在Swift中使用标准C库函数时,在传递C字符串时遇到了问题。作为一个简单示例(仅用于演示问题),标准C库函数
char * strdup(const char *s1);
暴露给Swift
func strdup(_: CString) -> UnsafePointer<CChar>
这意味着strdup()无法将返回值传递给另一个strdup()调用:
strdup()
let s1 : CString = "abc" let s2 = strdup(s1) // OK, s2 is a UnsafePointer<CChar> let s3 = strdup(s2) // error: could not find an overload for '__conversion' that accepts the supplied arguments
我的问题是: 如何建立一个斯威夫特CString从UnsafePointer<CChar>,使得由一个标准库函数返回的C字符串可以传递到另一个函数?
CString
UnsafePointer<CChar>
我能找到的唯一方法是使用“如何在Swift语言中将字符串转换为CString?”中的代码:
let s2a = String.fromCString(s2).bridgeToObjectiveC().UTF8String let s3 = strdup(s2a)
但是我发现这并不令人满意,原因有两个:
备注/背景: 当然,使用诸如Swift String或Objective-C之类的高级数据结构的高级函数NSString是更可取的。但是,标准C库中有BSD函数,它们在Foundation框架中没有完全对应的功能。
String
NSString
我在尝试回答在Swift中访问temp目录时遇到了这个问题。这里,mkdtemp()是一个BSD函数,没有确切的NSFileManager替代项(据我所知)。 mkdtemp()返回一个UnsafePointer<CChar>必须被传递给 NSFileManager函数stringWithFileSystemRepresentation这需要一个CString 说法。
mkdtemp()
NSFileManager
stringWithFileSystemRepresentation
更新: 从Xcode 6 beta 6开始,此问题不再存在,因为已简化了C字符串到Swift的映射。你可以写
let s1 = "abc" // String let s2 = strdup(s1) // UnsafeMutablePointer<Int8> let s3 = strdup(s2) // UnsafeMutablePointer<Int8> let s4 = String.fromCString(s3) // String
Swift 1.1(或更早的版本)具有更好的C字符串桥接功能:
let haystack = "This is a simple string" let needle = "simple" let result = String.fromCString(strstr(haystack, needle))
该CString类型是完全消失。