Swift 字符串文字赋值给 C 变量

Tro*_*vey 2 swift

在 Swift 中,当调用 C 函数时,Swift 字符串作为参数传递时会被自动强制转换为 CString。但是,在填写 C 结构或全局变量时,我没有得到相同的行为。

strlen(swiftString)                     //Works!
CGlobalStruct.stringPtr = swiftString   //Doesn't work!
Run Code Online (Sandbox Code Playgroud)

首先,当它们都是“const *char”时,为什么它们的行为不同。其次,填写C Structs的最干净方法是什么?

Mar*_*n R 5

SwiftString可以作为参数传递给带参数的函数UnsafePointer<Int8>。编译器将 Swift 字符串的临时表示生成为 NUL 终止的序列,char并将指向该 C 字符串的指针传递给函数。表示和指针仅在函数调用期间有效。这就是发生在

strlen(swiftString)   
Run Code Online (Sandbox Code Playgroud)

在分配全局 C 字符串指针时,您必须考虑该指针的生命周期。一种可能性是

let swiftString = "Hello world"

swiftString.withCString {
    CGlobalStruct.stringPtr = $0

    // Pointer valid inside this closure ...
}
// Pointer not valid anymore ...
Run Code Online (Sandbox Code Playgroud)

其中一个指向 C 字符串表示的指针被传递给闭包。该指针(仅)在闭包执行期间有效。

对于更长时间的使用,您可以在内存中分配一个 C 字符串,但您最终要负责释放该内存:

guard let cStringPtr = strdup(swiftString) else {
    fatalError("strdup failed")
}
CGlobalStruct.stringPtr = UnsafePointer(cStringPtr)

// ...

free(cStringPtr)
Run Code Online (Sandbox Code Playgroud)