开发者问题收集

将 swift 结构指针传递给 C 函数

2014-08-04
4185

假设我有一个名为 Foo 的 Swift 结构

struct Foo
{
     var a,b,c : Float
     var d : Double
     init()
     {
        a = 0
        b = 0
        c = 0
        d = 0
     }
}

Swift sizeof(Foo) 打印 24 个字节,4 个字节用于 Float 字段,8 个字节用于 Double,4 个字节用于 arm64 上的填充。

因此,我认为,完成结构对齐后,Swift 没有什么特殊的魔法,我们可以自由地将指向它的指针传递给内部 C 函数,以便使用 NEON 和 Metal 之类的东西,只要内置变量是联合体,而这些变量目前不能直接包含在 Swift 中

不知何故,当我尝试使用 const void* (Swift 中的 ConstUnsafePointer<()>) 时

let a = Foo()
let b = &a

我在第二个表达式上收到严重的编译器错误

'Foo' is not convertible to '@lvalue inout $T1'

我是否遗漏了什么,这是由设计?

更新部分

Martn R,谢谢您的回答!不过,整个情况对我来说还不是很清楚。我的目标是创建方便的数学内容包装器,所以我想实现 @infix 方法,如乘法,并将所有内部本机内容隐藏在 C 后面。例如,在矩阵的情况下,这意味着我们需要从 a = &b*&c 表达式中直接提取 & 符号,因为我没有从您的答案和文档中得到是否有办法绕过这一点并在 @infix 方法实现的范围内从内存中获取原始点。

像这样:

@infix public func *(l: Mat4, r: Mat4) -> Mat4
{
    var m = Mat4()
    _internalMat4Multiply(&l, &r, &m)
}

_internalMat4Multiply 是 void(void*, void*, void*) C 方法,执行所有计算

1个回答

有两个问题:您不能获取 常量 (用 let 定义)的地址, 并且您只能将变量的地址传递给函数参数。 假设您的 C 函数是

void myFunc(const void *data);

那么这将有效:

var a = Foo()
myFunc(&a)

但是,您不应该假设 C 和 Swift 中的对齐方式相同, 您最好在 C API 中定义结构:

struct Foo {
    float a;
    float b;
    float c;
    double d;
};

void myFunc(const struct Foo *data);

并从 Swift 代码中使用它:

var a = Foo(a: 0, b: 0, c: 0, d: 0)
myFunc(&a)
Martin R
2014-08-04