[英]Swift 3: Compilation error converting String Array to C Char Array
I have the following C struct: 我有以下C结构:
typedef struct {
char** categories;
int category_size;
} category_fmc_s_type;
My Swift array has the following values: 我的Swift数组具有以下值:
let categories = ["Weekday", "Weekend"]
I want to populate the C Struct field 'categories' with 'Weekday' & 'Weekend'. 我想用'Weekday'和'Weekend'填充C Struct字段'categories'。 To do this I call my toPointer():
要做到这一点,我调用我的toPointer():
fileprivate static func toPointer(_ args: [String]) -> UnsafeMutablePointer<UnsafeMutablePointer<Int8>> {
let buffer = UnsafeMutablePointer<UnsafeMutablePointer<Int8>>.allocate(capacity: args.count)
for (index, value) in args.enumerated() {
buffer[index] = UnsafeMutablePointer<Int8>(mutating: (value as NSString).utf8String!)
}
return buffer
}
I keep getting the following XCode 8 error: 我一直收到以下XCode 8错误:
Cannot convert value of type 'UnsafeMutablePointer<UnsafeMutablePointer<Int8>>' to expected argument type 'UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>!'
Any suggestions? 有什么建议么? I don't understand why there is the optional and '!'
我不明白为什么有可选和'!' in the C-Struct definition implicitly.
隐含地在C-Struct定义中。
As the compiler emits as an error, you need to unwrap after Int8 w/ " ? " as follows. 当编译器作为错误发出时,你需要在Int8之后用 “ ? ”解开,如下所示。
fileprivate func toPointer(_ args: [String]) -> UnsafeMutablePointer<UnsafeMutablePointer<Int8>?> {
let buffer = UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>.allocate(capacity: args.count)
for (index, value) in args.enumerated() {
buffer[index] = UnsafeMutablePointer<Int8>(mutating: (value as NSString).utf8String!)
}
return buffer
}
then, 然后,
func testMyCat() {
let categories = ["Weekday", "Weekend"]
let buffer = toPointer(categories)
var mycat = category_fmc_s_type()
mycat.categories = buffer // you would see compile error w/o "?"
}
the code above works w/o error. 上面的代码没有错误。 Martin's solution gives a compile error at
Martin的解决方案给出了编译错误
mycat.categories = &cargs (see the link) mycat.categories =&cargs(见链接)
I don't know why. 我不知道为什么。
Check the reference of utf8String
property of NSString
: 检查
NSString
的utf8String
属性的引用 :
Discussion
讨论
This C string is a pointer to a structure inside the string object, which may have a lifetime shorter than the string object and will certainly not have a longer lifetime.
此C字符串是指向字符串对象内部结构的指针,该结构的生命周期可能短于字符串对象,并且肯定不会有更长的生命周期。 Therefore, you should copy the C string if it needs to be stored outside of the memory context in which you use this property.
因此, 如果需要将C字符串存储在使用此属性的内存上下文之外,则应将其复制 。
The term memory context is not well-defined, but one thing sure is that you cannot expect the allocated region for the C string would live forever. 术语内存上下文没有明确定义,但有一点可以肯定的是,您不能指望C字符串的已分配区域将永远存在。 When the member
categories
in the category_fmc_s_type
is accessed, the pointers may be pointing to the already freed regions. 当访问
category_fmc_s_type
的成员categories
时,指针可以指向已经释放的区域。
Applying the suggestion from Martin R to your code, your code would be like this: 将Martin R的建议应用到您的代码中,您的代码将如下所示:
fileprivate static func toPointer(_ args: [String]) -> UnsafeMutablePointer<UnsafeMutablePointer<Int8>?> {
let buffer = UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>.allocate(capacity: args.count)
buffer.initialize(from: args.lazy.map{strdup($0)})
return buffer
}
And remember, after you finish using the category_fmc_s_type
, you need to deallocate the regions allocated by strdup(_:)
and UnsafeMutablePointer.allocate(capacity:)
: 请记住,在使用
category_fmc_s_type
,需要释放由strdup(_:)
和UnsafeMutablePointer.allocate(capacity:)
分配的区域:
fileprivate static func freePointer(_ pointers: UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>, count: Int) {
for i in 0..<count {
free(pointers[i])
}
pointers.deinitialize(count: count)
pointers.deallocate(capacity: count)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.