Ric*_*hiy 6 c arrays string pointers swift
我在库中有以下 C 风格结构:
typedef struct ServiceParam
{
const char *name;
const char *value;
} ServiceParam;
Run Code Online (Sandbox Code Playgroud)
我有兴趣从 Swift 初始化这些结构的数组,这是我尝试过的:
let cHeaders = headers.map{ServiceParam(name: $0.name, value: $0.value)}
Run Code Online (Sandbox Code Playgroud)
但收到以下警告:
将“String”传递给参数,但参数“value”应该是一个比“init(name:value:)”调用更长久的指针
和C 参数以name的value形式进行转换UnsafePointer<CChar>!,输入类型为(name: String, value: String),即 Swift-tuple,但我可以灵活地更改初始类型。
因此,整个最小示例如下所示:
public func setParams(headers: [(name: String, value: String)] = []) {
let cHeaders = headers.map{ServiceParam(name: $0.name, value: $0.value)}
// Do the work with `cHeaders`
}
Run Code Online (Sandbox Code Playgroud)
从 Swift 调用站点初始化上述 C 风格结构的最佳方法是什么?
该ServiceParam结构仅在父函数调用期间临时使用,但name和value字符串作为 C++ 对存储在数组中,并且它们的生命周期在函数返回后继续:
稍后的:
const auto paramPair = std::make_pair(params->name, params->value);
instance_variable_array.push_back(paramPair);
Run Code Online (Sandbox Code Playgroud)
当将 Swift 字符串传递给带有const char *参数的 C 函数时,会自动创建临时 C 字符串表示形式。但是,该 C 字符串仅在函数调用期间有效。这就是发生在
ServiceParam(name: $0.name, value: $0.value)
Run Code Online (Sandbox Code Playgroud)
并导致警告。有一种withCString方法可用于创建在某些范围内有效的 C 字符串表示形式:
name.withCString { cName in
value.withCString { cValue in
let sp = ServiceParam(name: cName, value: cValue)
// Do something with sp ...
}
}
Run Code Online (Sandbox Code Playgroud)
但同样,在执行离开这些作用域后,C 字符串指针无效。
为了延长 C 字符串的生命周期,您可以复制内存并稍后释放它:
let cHeaders = headers.map{ ServiceParam(name: strdup($0.name),
value: strdup($0.value)) }
// Do the work with `cHeaders`
for header in cHeaders {
free(UnsafeMutablePointer(mutating: header.name))
free(UnsafeMutablePointer(mutating: header.value))
}
Run Code Online (Sandbox Code Playgroud)