我有以下C结构:
typedef struct {
char** categories;
int category_size;
} category_fmc_s_type;
My Swift数组具有以下值:
let categories = ["Weekday", "Weekend"]
我想填充C Struct字段'类别'与工作日' &安培; '周末&#39 ;.要做到这一点,我调用我的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
}
我一直收到以下XCode 8错误:
Cannot convert value of type 'UnsafeMutablePointer<UnsafeMutablePointer<Int8>>' to expected argument type 'UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>!'
有什么建议吗?我不明白为什么有可选的&#39;!&#39;在隐含的C-Struct定义中。
答案 0 :(得分:0)
由于编译器发出错误,您需要在 Int8 w /“?”之后展开,如下所示。
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
}
然后,
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 "?"
}
上面的代码没有错误。 Martin's solution在
处出现编译错误mycat.categories =&amp; cargs(见链接)
我不知道为什么。
答案 1 :(得分:0)
检查reference of utf8String
property of NSString
:
讨论
此C字符串是指向字符串对象内部结构的指针, 它的寿命可能比字符串对象短,并且会 肯定没有更长的寿命。因此,你应该复制 C字符串,如果它需要存储在内存上下文中 你使用这个属性。
术语内存上下文没有明确定义,但有一点可以肯定的是,您不能指望C字符串的已分配区域将永远存在。访问categories
中的成员category_fmc_s_type
时,指针可能指向已经释放的区域。
将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
}
请记住,在使用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)
}