在Swift中使用C字符串,或者:如何转换UnsafePointer< CChar>到CString [英] Working with C strings in Swift, or: How to convert UnsafePointer<CChar> to CString

查看:367
本文介绍了在Swift中使用C字符串,或者:如何转换UnsafePointer< CChar>到CString的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Swift中使用标准C库函数时,在传递C字符串时遇到
的问题。作为一个简单示例(仅用于演示问题),标准C库函数

While playing with Standard C Library functions in Swift, I came across problems when passing C strings around. As a simple example (just to demonstrate the problem), the Standard C Library function

char * strdup(const char *s1);

暴露给Swift的原因是

is exposed to Swift as

func strdup(_: CString) -> UnsafePointer<CChar>

这意味着 strdup()无法传递给另一个 strdup()调用:

which means that the return value of strdup() cannot be passed to another strdup() call:

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

我的问题是:如何从 UnsafePointer< CChar>创建Swift CString
,以便可以将一个标准库函数返回的C字符串传递给另一个函数?

My question is: How to create a Swift CString from a UnsafePointer<CChar>, so that the C string returned by one standard library function can be passed to another function?

可以找到的是(使用如何使用Swift语言将字符串转换为CString?):

The only way that I could find is (using code from How do you convert a String to a CString in the Swift Language?):

let s2a = String.fromCString(s2).bridgeToObjectiveC().UTF8String
let s3 = strdup(s2a)

但是我发现这并不令人满意,有两个原因:

But I do not find this satisfying for two reasons:


  • 对于一个简单的任务来说太复杂了。

  • (主要原因:)上述转换仅在C字符串为有效的UTF-8
    字符串,否则它将因运行时异常而失败。但是C字符串是一个任意
    字符序列,由NUL字符分隔。

  • It is too complicated for a simple task.
  • (Main reason:) The above conversions works only if the C string is a valid UTF-8 string, otherwise it fails with a runtime exception. But a C string is an arbitrary sequence of characters, delimited by a NUL character.

备注/背景:当然,使用Swift等高级数据结构的高级函数 String 或Objective-C NSString 为佳。但是
标准C库中有BSD函数,在Foundation框架中没有完全对应的函数。

Remarks/Background: Of course, high-level functions using high-level data structures like Swift String or Objective-C NSString are preferable. But there are BSD functions in the Standard C Library which do not have an exact counterpart in the Foundation frameworks.

我在尝试回答时遇到了这个问题在Swift中访问临时目录
在这里, mkdtemp()是一个BSD函数,没有确切的 NSFileManager 替代品存在
(我所知道的)。
mkdtemp()返回 UnsafePointer< CChar> ,该值必须传递给
NSFileManager 函数 stringWithFileSystemRepresentation 需要一个 CString

I came across this problem while trying to answer Accessing temp directory in Swift. Here, mkdtemp() is a BSD function for which no exact NSFileManager replacement exists (as far as I know). mkdtemp() returns a UnsafePointer<CChar> which has to be passed to the NSFileManager function stringWithFileSystemRepresentation which takes a CString argument.

更新:截至Xcode 6 beta 6,此问题不再存在因为简化了C字符串到Swift的映射。您可以只写

Update: As of Xcode 6 beta 6, this problem does not exist anymore because the mapping of C-Strings into Swift has been simplified. You can just write

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字符串桥接:

Swift 1.1 (or perhaps earlier) has even better C string bridging:

let haystack = "This is a simple string"
let needle = "simple"
let result = String.fromCString(strstr(haystack, needle))

CString 类型已完全消失。

这篇关于在Swift中使用C字符串,或者:如何转换UnsafePointer&lt; CChar&gt;到CString的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆