Craig
(Craig)
1
I'm using a C library that returns a fixed-length array, which Swift represents as a tuple, but I'd like it as an array to iterate through it.
From the debugger screenshot below, in the watch expressions, SubFrame_Report_s is size 16, and a tuple of 4 SubFrame_Report_s values is size 32, but I would expect 64 (16 * 4).
Why am I getting 32 instead of 64 for this tuple?
MemoryLayout<Any>.size is the size of the Any container, not the size of the thing it wraps. this will always be 32 (on 64-bit platforms), it is part of the language ABI.
Craig
(Craig)
3
I thought it might be something like that; is there a way to fix this function signature to make this work?
it should work if you make from(tuple:start:) generic, something like:
static
func from<Tuple>(tuple:Tuple) -> Self
{
.init(unsafeUninitializedCapacity: MemoryLayout<Tuple>.size)
{
withUnsafeBytes(of: tuple) { ... }
}
}
ought to get you started.
(obviously, you need to be mindful of alignment, but it sounds like you’re already aware of that.)
tera
5
Try this one:
extension Array {
init<T>(_ value: inout T) {
self = Swift.withUnsafeBytes(of: &value) { p in
Self(
UnsafeBufferPointer(
start: p.bindMemory(to: Element.self).baseAddress!,
count: MemoryLayout<T>.size / MemoryLayout<Element>.stride)
)
}
}
}
// test (I'm using an array of C longs on the C side):
// long elements[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
let array = [Int](&elements)
print(array) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
It's also possible to remove inout and pass the argument by value (e.g. in order to pass const C arrays). In this case you'd need to have: "var value = value" internally.