将swift var传递给C api作为void **

时间:2018-01-15 07:25:59

标签: swift

我有一个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,所以我不确定是否可以进行这样的修改。如何传递一个可变值的指针?

2 个答案:

答案 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?'