我有一个C api,如下所示
struct foo_private_t;
typedef foo_private_t* foo_t;
void foo_func(void**x);
如果打算像这样使用API
foo_t x;
void foo_func((void**) &x);
为什么API采用void**
而不是foo_t*
超出了此问题的范围。问题是当我尝试从swift调用此API时。首先,我通过桥接头将C头导入swift。然后我尝试使用指向swift对象的指针调用foo_func。
var x:foo_t?
foo_func(&x)
// error is cannot convert value of type 'foo_t?' (aka 'Optional<OpaquePointer>') to expected argument type 'UnsafeMutableRawPointer?'
预计会出现错误,我需要一个指向指针的指针,所以我试过了。
withUnsafeMutablePointer(to: x){ x_p in foo_func(x_p) }
// error is cannot convert value of type 'UnsafeMutablePointer<_>' to expected argument type 'UnsafeMutablePointer<UnsafeMutableRawPointer?>!'
这似乎也是合理的,因为x_p
与&x
类似,只是一个指针级别。我本来期望的下一次尝试。
withUnsafeMutablePointer(to: x){ x_p in foo_func(&x_p) }
// error is cannot pass immutable value of type 'UnsafeMutableRawPointer?' as inout argument
搜索此错误会发现,如果我调用了swift函数,我应该使用inout
修饰符来参数。但是因为我正在调用C api,所以我不确定是否可以进行这样的修改。如何传递一个可变值的指针?
答案 0 :(得分:1)
如果打算将x
的地址传递给C函数
以foo_func()
可以为x
分配新值的方式
是什么C代码
foo_t x;
void foo_func((void**) &x);
确实如此)那将是:
var x: foo_t?
withUnsafeMutablePointer(to: &x) {
$0.withMemoryRebound(to: UnsafeMutableRawPointer?.self, capacity: 1) {
foo_func($0)
}
}
在withUnsafeMutablePointer()
内,$0
是
UnsafeMutablePointer<foo_t?>
这是反弹到预期类型的指针
UnsafeMutablePointer<UnsafeMutableRawPointer?>
答案 1 :(得分:0)
我能够让它发挥作用。
var e = UnsafeMutableRawPointer(x)
foo_func(&e)
x
已经是一个指针,因此它可以转换为原始指针。然后我需要一个指向该原始指针的指针,所以我取e
的地址。我想我需要e
变量,因为隐式临时值不能作为参数传递给inout
参数。 E.g。
foo_func(&UnsafeMutableRawPointer(x))
// error is cannot convert value of type 'foo_t?' (aka 'Optional<OpaquePointer>') to expected argument type 'UnsafeMutableRawPointer?'