Swift将字符串转换为UnsafeMutablePointer <Int8>

Ste*_*erg 12 pointers swift xcode6

我有一个映射到Swift的C函数定义为:

func swe_set_eph_path(path: UnsafeMutablePointer<Int8>) -> Void
Run Code Online (Sandbox Code Playgroud)

我试图传递一个路径到该功能,并尝试过:

        var path = [Int8](count: 1024, repeatedValue: 0);
        for i in 0...NSBundle.mainBundle().bundlePath.lengthOfBytesUsingEncoding(NSUTF16StringEncoding)-1
        {
            var range = i..<i+1
            path[i] = String.toInt(NSBundle.mainBundle().bundlePath[range])
        }
        println("\(path)")
        swe_set_ephe_path(&path)
Run Code Online (Sandbox Code Playgroud)

但在路径[i]行我得到错误:

'subscript'不可用:不能使用Int范围下标String

swe_set_ephe_path(NSBundle.mainBundle().bundlePath)
Run Code Online (Sandbox Code Playgroud)

也不

swe_set_ephe_path(&NSBundle.mainBundle().bundlePath)
Run Code Online (Sandbox Code Playgroud)

也不工作

除了没有工作,我觉得必须有一个更好,更少复杂的方式来做到这一点.使用CString的StackOverflow以前的答案似乎不再起作用了.有什么建议?

mat*_*att 23

使用CString的StackOverflow以前的答案似乎不再起作用了

不过,UnsafePointer<Int8>是一个C字符串.如果您的上下文绝对需要UnsafeMutablePointer,只需强制,像这样:

let s = NSBundle.mainBundle().bundlePath
let cs = (s as NSString).UTF8String
var buffer = UnsafeMutablePointer<Int8>(cs)
swe_set_ephe_path(buffer)
Run Code Online (Sandbox Code Playgroud)

当然我没有你的swe_set_ephe_path,但它在我的测试中运行正常,如下所示:

func swe_set_ephe_path(path: UnsafeMutablePointer<Int8>) {
    println(String.fromCString(path))
}
Run Code Online (Sandbox Code Playgroud)

  • 使用Swift 4,这给了我:无法使用类型'(UnsafePointer <Int8>)'的参数列表调用类型'UnsafeMutablePointer <Int8>'的初始值设定项 (6认同)
  • @agirault 将 `mutating:` 作为参数标签添加到 UnsafeMutablePointer 初始值设定项。`var buffer = UnsafeMutablePointer&lt;Int8&gt;(mutating: cs)` (3认同)

Les*_*ary 10

在当前版本的Swift语言中,您可以这样做(其他答案已过时):

let path = Bundle.main.bundlePath
let param = UnsafeMutablePointer<Int8>(mutating: (path as NSString).utf8String)
Run Code Online (Sandbox Code Playgroud)

  • “Swift 语言的当前版本”到底是什么? (2认同)

Air*_*ity 8

它实际上非常刺激您正在使用的库(它在C声明中)char * path而不是const char * path.(这假设函数不会改变输入字符串 - 如果确实如此,则处于完全不同的情况).

如果没有,该函数将转到Swift:

// note, UnsafePointer not UnsafeMutablePointer
func swe_set_eph_path(path: UnsafePointer<Int8>) -> Void
Run Code Online (Sandbox Code Playgroud)

然后你可以依赖Swift的隐式转换:

let str = "blah"
swe_set_eph_path(str) // Swift implicitly converts Strings 
                      // to const C strings when calling C funcs
Run Code Online (Sandbox Code Playgroud)

但是你可以很容易地进行不安全的转换,结合withCString函数:

str.withCString { cstr in
    swe_set_eph_path(UnsafeMutablePointer(cstr))
}
Run Code Online (Sandbox Code Playgroud)


Joh*_*nes 7

我有一个someLibrary.a用iOS编写的用C++编写的静态库().头文件(someLibrary.h)有一个像这样暴露的函数:

extern long someFunction(char* aString);

Swift中的声明如下所示:

Int someFunction(aString: UnsafeMutablePointer<Int8>)

我做了一个扩展String:

extension String {
    var UTF8CString: UnsafeMutablePointer<Int8> {
        return UnsafeMutablePointer((self as NSString).UTF8String)
    }
}
Run Code Online (Sandbox Code Playgroud)

那么我可以像这样调用方法:

someFunction(mySwiftString.UTF8CString)