在Swift中使用标准C库函数时,我遇到了问题 当传递C字符串时。作为一个简单的例子(仅用于演示问题),标准C库函数
char * strdup(const char *s1);
以暴露于Swift
func strdup(_: CString) -> UnsafePointer<CChar>
表示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
创建Swift UnsafePointer<CChar>
,
这样一个标准库函数返回的C字符串可以传递给另一个函数吗?
我能找到的唯一方法是(使用How do you convert a String to a CString in the Swift Language?中的代码):
let s2a = String.fromCString(s2).bridgeToObjectiveC().UTF8String
let s3 = strdup(s2a)
但我认为这并不令人满意,原因有两个:
备注/背景:当然,使用Swift String
或Objective-C NSString
等高级数据结构的高级函数更可取。但是有BSD功能
标准C库,在Foundation框架中没有完全对应的。
我在尝试回答Accessing temp directory in Swift时遇到了这个问题。
这里,mkdtemp()
是一个BSD函数,不存在精确的NSFileManager
替换
(我所知道的)。
mkdtemp()
返回UnsafePointer<CChar>
,必须将其传递给。{1}}
NSFileManager
函数stringWithFileSystemRepresentation
,CString
参数。
更新:从Xcode 6 beta 6开始,这个问题不再存在,因为C-Strings到Swift的映射已经简化了。你可以写
let s1 = "abc" // String
let s2 = strdup(s1) // UnsafeMutablePointer<Int8>
let s3 = strdup(s2) // UnsafeMutablePointer<Int8>
let s4 = String.fromCString(s3) // String
答案 0 :(得分:17)
Swift 1.1(或者可能更早)有更好的C字符串桥接:
let haystack = "This is a simple string"
let needle = "simple"
let result = String.fromCString(strstr(haystack, needle))
CString
类型已完全消失。
答案 1 :(得分:0)
Swift中的String结构具有一个初始化例程,您可以像这样使用它:
let myString = String(cString: myUnsafePointer)