在Swift中使用标准C库函数时,我在传递C字符串时遇到了问题.作为一个简单的例子(仅用于演示问题),标准C库函数
char * strdup(const char *s1);
Run Code Online (Sandbox Code Playgroud)
接触Swift作为
func strdup(_: CString) -> UnsafePointer<CChar>
Run Code Online (Sandbox Code Playgroud)
这意味着返回值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
Run Code Online (Sandbox Code Playgroud)
我的问题是:如何CString
从a 创建一个Swift UnsafePointer<CChar>
,以便一个标准库函数返回的C字符串可以传递给另一个函数?
我能找到的唯一方法是(使用Swift语言中如何将字符串转换为CString的代码?):
let s2a = String.fromCString(s2).bridgeToObjectiveC().UTF8String
let s3 = strdup(s2a)
Run Code Online (Sandbox Code Playgroud)
但我认为这并不令人满意,原因有两个:
备注/背景:当然,使用Swift String
或Objective-C 等高级数据结构的高级函数NSString
更可取.但是标准C库中有BSD功能,它们在Foundation框架中没有完全对应的功能.
我在尝试回答Swift中的Accessing临时目录时遇到了这个问题.这里mkdtemp()
是一个没有确切NSFileManager
替换的BSD函数(据我所知).
mkdtemp()
返回一个UnsafePointer<CChar>
必须被传递给
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
Run Code Online (Sandbox Code Playgroud)
Nat*_*ook 18
Swift 1.1(或许更早)有更好的C字符串桥接:
let haystack = "This is a simple string"
let needle = "simple"
let result = String.fromCString(strstr(haystack, needle))
Run Code Online (Sandbox Code Playgroud)
该CString
类型是完全消失.
Swift 中的 String 结构有一个 init 例程,您可以像这样使用:
let myString = String(cString: myUnsafePointer)
Run Code Online (Sandbox Code Playgroud)
另请参见init(cString: UnsafePointer)
归档时间: |
|
查看次数: |
16358 次 |
最近记录: |