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

Eli*_*gny 3 struct pointers ios swift

比方说,我有一个名为Foo的Swift结构

struct Foo
{
     var a,b,c : Float
     var d : Double
     init()
     {
        a = 0
        b = 0
        c = 0
        d = 0
     }
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

我在第二个表达式上遇到令人讨厌的编译错误

'Foo' is not convertible to '@lvalue inout $T1'
Run Code Online (Sandbox Code Playgroud)

我错过了什么,这是通过设计完成的吗?

更新部分

Martn R,谢谢你的回答!不过,对我来说,整个情况并不是很清楚.我的目标是创建方便的Math stuff包装器,所以我想实现像乘法一样的@ infix方法并隐藏C后面的所有内部本机东西.例如,对于Matrices,这意味着我们需要从a =中拉出&符号&b*&c表达式,因为如果有办法绕过这个并且在@infix方法实现的范围内从内存中获取原始点,我没有得到你的答案和Docs.

像这样:

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

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

Mar*_*n R 6

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

void myFunc(const void *data);
Run Code Online (Sandbox Code Playgroud)

然后这会工作:

var a = Foo()
myFunc(&a)
Run Code Online (Sandbox Code Playgroud)

但是,您可以更好地在C API中定义结构,而不是在C和Swift中对相同的对齐进行假设:

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

void myFunc(const struct Foo *data);
Run Code Online (Sandbox Code Playgroud)

并使用Swift代码:

var a = Foo(a: 0, b: 0, c: 0, d: 0)
myFunc(&a)
Run Code Online (Sandbox Code Playgroud)