Reputation: 65
Let's say, I have Swift struct named Foo
struct Foo
{
var a,b,c : Float
var d : Double
init()
{
a = 0
b = 0
c = 0
d = 0
}
}
Swift sizeof(Foo) prints 24 bytes, 4 bytes for Float fields, 8 for Double and 4 bytes of padding on arm64.
So I consider, that there is no special Swift magic with structures alignment done, and we can freely pass pointers to it to internal C functions in order to use stuff like NEON and Metal, as long as built-in variables are unions, which currently can't be directly included into Swift
Somehow, when I try to get const void* to it (ConstUnsafePointer<()> in Swift) with
let a = Foo()
let b = &a
I get nasty compiler error on second expression
'Foo' is not convertible to '@lvalue inout $T1'
Did I miss something and this is done by design?
Martn R, thanks for answer! Still, entire situation is not very clear for me. My aim was to create convenient Math stuff wrapper, so I wanted to implement @infix methods like multiplication and hide all internal native stuff behind C. In case of Matrices, for example, that means, that we need to pull ampersand right from a = &b*&c expressions, because I didn't get from your answer and Docs if there is a way to bypass this and get raw point from memory in the scope of @infix method implementation.
Like this:
@infix public func *(l: Mat4, r: Mat4) -> Mat4
{
var m = Mat4()
_internalMat4Multiply(&l, &r, &m)
}
_internalMat4Multiply is void(void*, void*, void*) C-method, doing all the computations
Upvotes: 3
Views: 4234
Reputation: 539715
There are two problems: You cannot take the address of a constant (defined with let
),
and you can pass the address of a variable only to function parameters.
Assuming that your C function is
void myFunc(const void *data);
then this would work:
var a = Foo()
myFunc(&a)
However, instead of making assumptions about identical alignment in C and Swift, you should perhaps better define the structure in your C API:
struct Foo {
float a;
float b;
float c;
double d;
};
void myFunc(const struct Foo *data);
and use that from the Swift code:
var a = Foo(a: 0, b: 0, c: 0, d: 0)
myFunc(&a)
Upvotes: 7