简体   繁体   English

Swift 将字符串转换为 UnsafeMutablePointer<int8></int8>

[英]Swift convert string to UnsafeMutablePointer<Int8>

I have a C function mapped to Swift defined as:我有一个 C function 映射到 Swift 定义为:

func swe_set_eph_path(path: UnsafeMutablePointer<Int8>) -> Void

I am trying to pass a path to the function and have tried:我正在尝试将路径传递给 function 并尝试过:

        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)

but on the path[i] line I get the error:但是在 path[i] 行我得到了错误:

'subscript' is unavailable: cannot subscript String with a range of Int “下标”不可用:无法下标具有 Int 范围的字符串

swe_set_ephe_path(NSBundle.mainBundle().bundlePath)

nor也不

swe_set_ephe_path(&NSBundle.mainBundle().bundlePath)

don't work either也不工作

Besides not working, I feel there has got to be a better, less convoluted way of doing this.除了不工作之外,我觉得必须有一种更好、更简单的方法来做到这一点。 Previous answers on StackOverflow using CString don't seem to work anymore.以前使用 CString 的 StackOverflow 答案似乎不再有效。 Any suggestions?有什么建议么?

Previous answers on StackOverflow using CString don't seem to work anymore 使用CString的StackOverflow以前的答案似乎不再起作用了

Nevertheless, UnsafePointer<Int8> is a C string. 然而, UnsafePointer<Int8>是一个C字符串。 If your context absolutely requires an UnsafeMutablePointer , just coerce, like this: 如果你的上下文绝对需要一个UnsafeMutablePointerUnsafeMutablePointer强迫一下,像这样:

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

Of course I don't have your swe_set_ephe_path , but it works fine in my testing when it is stubbed like this: 当然我没有你的swe_set_ephe_path ,但它在我的测试中工作得很好,因为它是这样的存根:

func swe_set_ephe_path(path: UnsafeMutablePointer<Int8>) {
    println(String.fromCString(path))
}

It's actually extremely irritating of the library you're using that it requires (in the C declaration) a char * path rather than const char * path . 它实际上非常刺激你正在使用的库,它需要(在C声明中)一个char * path而不是const char * path (this is assuming the function doesn't mutate the input string – if it does, you're in a whole different situation). (这假设函数不会改变输入字符串 - 如果确实如此,则处于完全不同的情况)。

If it didn't, the function would come over to Swift as: 如果没有,该函数将转到Swift:

// note, UnsafePointer not UnsafeMutablePointer
func swe_set_eph_path(path: UnsafePointer<Int8>) -> Void

and you could then rely on Swift's implicit conversion: 然后你可以依赖Swift的隐式转换:

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

But you can do an unsafe conversion quite easily, in combination with the withCString function: 但是你可以很容易地进行不安全的转换,结合withCString函数:

str.withCString { cstr in
    swe_set_eph_path(UnsafeMutablePointer(cstr))
}

In current version of Swift language you can do it like this (other answers are outdated): 在当前版本的Swift语言中,您可以这样做(其他答案已过时):

let path = Bundle.main.bundlePath
let param = UnsafeMutablePointer<Int8>(mutating: (path as NSString).utf8String)

I had a static library ( someLibrary.a ) written in C++ compiled for iOS. 我有一个用iOS编写的用C ++编写的静态库( someLibrary.a )。 The header file ( someLibrary.h ) had a function exposed like this: 头文件( someLibrary.h )有一个像这样暴露的函数:

extern long someFunction(char* aString);

The declaration in Swift looks like this: Swift中的声明如下所示:

Int someFunction(aString: UnsafeMutablePointer<Int8>)

I made an extension to String : 我对String进行了扩展:

extension String {
    var UTF8CString: UnsafeMutablePointer<Int8> {
        return UnsafeMutablePointer((self as NSString).UTF8String)
    }
}

So then I can call the method like so: 那么我可以像这样调用方法:

someFunction(mySwiftString.UTF8CString)

Update: Make String extension (swift 5.7)更新:制作字符串扩展(swift 5.7)

extension String {
    var UTF8CString: UnsafeMutablePointer<Int8> {
        return UnsafeMutablePointer(mutating: (self as NSString).utf8String!)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM