I have this code right here that worked in preexisting swift.
func toByteArray<T>(_ value: T) -> [UInt8] {
var val = value
//let sock = socket(PF_INET, SOCK_STREAM, 0) // added in 11/16
return withUnsafePointer(to: &val) {
Array(UnsafeBufferPointer(start: UnsafePointer<UInt8>($0), count: MemoryLayout<T>.size))
}
}
This does not work, as it prints an error message that says init is unavailable. Use withMemoryRebound(to:capacity:_). Ok, so I have researched through google and found some options that should work, where now my updated code is
func toByteArray<T>(_ value: T) -> [UInt8] {
var val = value
return withUnsafePointer(to: &val) {
//another swift 3 change with UnsafePointer<UInt8>
Array(UnsafeBufferPointer(start: ($0).withMemoryRebound(to:UInt8.self, capacity: 1){ SCNetworkReachabilityCreateWithAddress(nil, $0)}, count: MemoryLayout<T>.size))
}
}
Which should work, however it says use of unresolved identifier SCNetworkReachabilityCreateWithAddress, which I don't understand and can't find a solution for it. Any thoughts on what the issue is? I feel it is something that is with the updated Swift and Xcode.
I wonder if making an Array of UInt8 would be the best solution for your actual purpose.
For example, Data works as a Collection of UInt8 in Swift 3.
func toData<T>(_ value: T) -> Data {
var val = value
return Data(bytes: &val, count: MemoryLayout<T>.size)
}
for byte in toData(i) {
print(String(format: "%02X", byte))
}
/* output:
78
56
34
12
00
00
00
00
*/
But if you insist on using Array, you can write something like this using UnsafeRawBufferPointer (available since Swift 3.0.1/Xcode 8.1):
func toByteArray<T>(_ value: T) -> [UInt8] {
var val = value
return Array(UnsafeRawBufferPointer(start: &val, count: MemoryLayout<T>.size))
}
Try this:
func toByteArray<T>(_ value: T) -> Any {
var value = value
let pointerToT = withUnsafePointer(to: &value) { UnsafeRawPointer($0) }
let sizeOfT = MemoryLayout<T>.size
let pointerToBytes = pointerToT.bindMemory(to: UInt8.self, capacity: sizeOfT)
let bytes = Array(UnsafeBufferPointer(start: bytePointer, count: sizeOfT))
return bytes
}
Related
Within my app, I have a MTLBuffer which is being instantiated using a generic type. In one particular case, the buffer will hold values as related to particles in a point cloud, and is defined as such;
struct ParticleUniforms {
simd_float3 position;
simd_float3 color;
float confidence;
};
I am instantiating my MTLBuffer like so;
guard let buffer = device.makeBuffer(length: MemoryLayout<Element>.stride * count, options: options) else {
fatalError("Failed to create MTLBuffer.")
}
Where I am struggling, however, is to understand how to read the contents of the buffer. More-so, I am looking to copy one element of each item in the buffer to an array on the CPU, which I will use at a later time.
Effectively, the buffer holds a collection of ParticleUniforms, and I would like to access the position value of each item, saving that position to a separate array.
All of the examples I've seen here on Stack Overflow seem to show the MTLBuffer as holding a collection of Floats, though I've not seen any that use a generic type.
It seems what you are looking to achieve can only be done with C structures which hold each member in a contiguous block (arrays of C structs are not necessarily contiguous, but MemoryLayout<Type>.stride will account for any potential padding). Swift structure properties may not be contiguous, so the below method for accessing member values would not work in a practical manner. Unfortunately, when working with void* you need to know what the data describes, which isn't particularly suited for Swift generic types. However, I will offer a potential solution.
C file:
#ifndef Test_h
#define Test_h
#include <simd/simd.h>
typedef struct {
vector_float3 testA;
vector_float3 testB;
} CustomC;
#endif /* Test_h */
Swift file (bridging header assumed)
import Metal
// MARK: Convenience
typealias MTLCStructMemberFormat = MTLVertexFormat
#_functionBuilder
struct ArrayLayout { static func buildBlock<T>(_ arr: T...) -> [T] { arr } }
extension MTLCStructMemberFormat {
var stride: Int {
switch self {
case .float2: return MemoryLayout<simd_float2>.stride
case .float3: return MemoryLayout<simd_float3>.stride
default: fatalError("Case unaccounted for")
}
}
}
// MARK: Custom Protocol
protocol CMetalStruct {
/// Returns the type of the `ith` member
static var memoryLayouts: [MTLCStructMemberFormat] { get }
}
// Custom Allocator
class CustomBufferAllocator<Element> where Element: CMetalStruct {
var buffer: MTLBuffer!
var count: Int
init(bytes: UnsafeMutableRawPointer, count: Int, options: MTLResourceOptions = []) {
guard let buffer = device.makeBuffer(bytes: bytes, length: count * MemoryLayout<Element>.stride, options: options) else {
fatalError("Failed to create MTLBuffer.")
}
self.buffer = buffer
self.count = count
}
func readBufferContents<T>(element_position_in_array n: Int, memberID: Int, expectedType type: T.Type = T.self)
-> T {
let pointerAddition = n * MemoryLayout<Element>.stride
let valueToIncrement = Element.memoryLayouts[0..<memberID].reduce(0) { $0 + $1.stride }
return buffer.contents().advanced(by: pointerAddition + valueToIncrement).bindMemory(to: T.self, capacity: 1).pointee
}
func extractMembers<T>(memberID: Int, expectedType type: T.Type = T.self) -> [T] {
var array: [T] = []
for n in 0..<count {
let pointerAddition = n * MemoryLayout<Element>.stride
let valueToIncrement = Element.memoryLayouts[0..<memberID].reduce(0) { $0 + $1.stride }
let contents = buffer.contents().advanced(by: pointerAddition + valueToIncrement).bindMemory(to: T.self, capacity: 1).pointee
array.append(contents)
}
return array
}
}
// Example
// First extend the custom struct to conform to out type
extension CustomC: CMetalStruct {
#ArrayLayout static var memoryLayouts: [MTLCStructMemberFormat] {
MTLCStructMemberFormat.float3
MTLCStructMemberFormat.float3
}
}
let device = MTLCreateSystemDefaultDevice()!
var CTypes = [CustomC(testA: .init(59, 99, 0), testB: .init(102, 111, 52)), CustomC(testA: .init(10, 11, 5), testB: .one), CustomC(testA: .zero, testB: .init(5, 5, 5))]
let allocator = CustomBufferAllocator<CustomC>(bytes: &CTypes, count: 3)
let value = allocator.readBufferContents(element_position_in_array: 1, memberID: 0, expectedType: simd_float3.self)
print(value)
// Prints SIMD3<Float>(10.0, 11.0, 5.0)
let group = allocator.extractMembers(memberID: 1, expectedType: simd_float3.self)
print(group)
// Prints [SIMD3<Float>(102.0, 111.0, 52.0), SIMD3<Float>(1.0, 1.0, 1.0), SIMD3<Float>(5.0, 5.0, 5.0)]
This is similar to a MTLVertexDescriptor, except the memory is accessed manually and not via the [[stage_in]] attribute and the argument table passed to each instance of a vertex of fragment shader. You could even extend the allocator to accept a string parameter with the name of the property and hold some dictionary which maps to member IDs.
in
Swift4, the String is Collections. You will no longer use
characters property on a string.
func swapCharacters(input:String,index1:Int,index2:Int)-> String { // logic to swap }
let input = "ABCDEFGH"
If I call the function with (input,3,8) then the output should be
Output : ABCHEFGD
Note: In Swift4, Strings are collections.
Fairly straightforward since String is a collection:
func swapCharacters(input: String, index1: Int, index2: Int) -> String {
var characters = Array(input)
characters.swapAt(index1, index2)
return String(characters)
}
let input = "ABCDEFGH"
print(swapCharacters(input: input, index1: 3, index2: 7)) //ABCHEFGD
or, to provide a direct array-like operation:
extension String {
mutating func swapAt(_ index1: Int, _ index2: Int) {
var characters = Array(self)
characters.swapAt(index1, index2)
self = String(characters)
}
}
var input = "ABCDEFGH"
input.swapAt(3, 7)
print(input) //ABCHEFGD
If you are looking for String manipulation without converting it to array.
I won't say it's great solution, but does its job.
func swapCharacters(input: String, index1: Int, index2: Int) -> String {
var result = input
let index1Start = input.index(input.startIndex, offsetBy: index1)
let index1End = input.index(after: index1Start)
let index2Start = input.index(input.startIndex, offsetBy: index2)
let index2End = input.index(after: index2Start)
let temp = input[index2Start..<index2End]
result.replaceSubrange(index2Start..<index2End,
with: input[index1Start..<index1End])
result.replaceSubrange(index1Start..<index1End, with: temp)
return result
}
print(swapCharacters(input: "ABCDEFGH", index1: 3, index2: 7))
prints: ABCHEFGD
Your question doesn't make sense. Strings in Swift are not indexed by Int. You need to first figure out for yourself what a Character really is (an Extended Grapheme Cluster). Then you need to figure out why Int cannot be used as the index for Strings. And then you can come up with a real problem. Read up here:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html
With the new ways of handling string in Swift 4, I'm trying to wrap my head around how to write the equivalent of the Mid function from other languages (visual basic, etc), so that
let testString = "0123456"
print Mid(testString, 2,4) // "1234" (or "2345" would work too)
This question is the same idea, but everything there predates Swift 4. If the answer there by jlert is still the best way to do things in Swift 4, that works, although it seems like so much has changed that the best practice to do this may have changed as well.
One way to do it is with a combination of dropFirst and prefix and then use String to convert the result back to String:
let testString = "0123456"
func mid(_ str: String, _ low: Int, _ count: Int) -> String {
return String(str.dropFirst(low).prefix(count))
}
print(mid(testString, 2,4)) // 2345
dropFirst and prefix are forgiving and won't crash if enough letters are not there. They will just give a truncated result. Depending on how you define the function, this is a perfectly acceptable implementation.
Another approach would be to use array subscripting. If you do it that way, you need to check inputs to avoid Array index out of range fatal errors:
func mid(_ str: String, _ low: Int, _ count: Int) -> String? {
guard low >= 0,
count >= 0,
low < str.count,
low + count <= str.count
else { return nil }
return String(Array(str)[low ..< low + count])
}
let testString = "abcdefghi"
if let result = mid(testString, 2, 4) {
print(result) // cdef
}
You can do:
extension String {
func mid(_ startOffset: Int, _ length: Int) -> Substring {
let start = index(startIndex, offsetBy: startOffset, limitedBy: endIndex) ?? endIndex
let end = index(start, offsetBy: length, limitedBy: endIndex) ?? endIndex
return self[start ..< end]
}
}
let string = "0123456"
let result = string.mid(2, 4) // 2345
Note, this returns a Substring, which enjoys memory efficiency. But if you want a String, you can do :
let result = String(string.mid(2, 4))
(Or you can incorporate this in your mid function.)
I would take a different approach using String.Index and return a Substring instead of a new String object. You can also add precondition to restrict improper use of that method:
func mid(_ string: String, _ positon: Int, length: Int) -> Substring {
precondition(positon < string.count, "invalid position")
precondition(positon + length <= string.count, "invalid substring length")
let lower = string.index(string.startIndex, offsetBy: positon)
let upper = string.index(lower, offsetBy: length)
return string[lower..<upper]
}
let testString = "0123456"
mid(testString, 2, length: 4) // "2345"
Another option would be creating that method as a string extension:
extension String {
func mid(_ positon: Int, length: Int) -> Substring {
precondition(positon < count, "invalid position")
precondition(positon + length <= count, "invalid substring length")
let lower = index(startIndex, offsetBy: positon)
let upper = index(lower, offsetBy: length)
return self[lower..<upper]
}
}
let testString = "0123456"
testString.mid(2, length: 4) // "2345"
iOS 14, Swift 5... same thing as vacawama excellent answer, but as an extension, so it's even less code :)
extension String {
func mid(_ low: Int, _ count: Int) -> String {
return String(self.dropFirst(low).prefix(count))
}
}
Use it like this.
let pString = "01234567"
for i in 0 ..< 8 {
print("\(i) \(pString.mid(i,1)")
}
Prints out your string to the console, one character at a time
With Swift 3 leaning towards Data instead of [UInt8], I'm trying to ferret out what the most efficient/idiomatic way to encode/decode swifts various number types (UInt8, Double, Float, Int64, etc) as Data objects.
There's this answer for using [UInt8], but it seems to be using various pointer APIs that I can't find on Data.
I'd like to basically some custom extensions that look something like:
let input = 42.13 // implicit Double
let bytes = input.data
let roundtrip = bytes.to(Double) // --> 42.13
The part that really eludes me, I've looked through a bunch of the docs, is how I can get some sort of pointer thing (OpaquePointer or BufferPointer or UnsafePointer?) from any basic struct (which all of the numbers are). In C, I would just slap an ampersand in front of it, and there ya go.
Note: The code has been updated for Swift 5 (Xcode 10.2) now. (Swift 3 and Swift 4.2 versions can be found in the edit history.) Also possibly unaligned data is now correctly handled.
How to create Data from a value
As of Swift 4.2, data can be created from a value simply with
let value = 42.13
let data = withUnsafeBytes(of: value) { Data($0) }
print(data as NSData) // <713d0ad7 a3104540>
Explanation:
withUnsafeBytes(of: value)
invokes the closure with a buffer pointer covering the raw bytes of the value.
A raw buffer pointer is a sequence of bytes, therefore Data($0) can be used to create the data.
How to retrieve a value from Data
As of Swift 5, the withUnsafeBytes(_:) of Data invokes the closure with an “untyped” UnsafeMutableRawBufferPointer to the bytes. The load(fromByteOffset:as:) method the reads the value from the memory:
let data = Data([0x71, 0x3d, 0x0a, 0xd7, 0xa3, 0x10, 0x45, 0x40])
let value = data.withUnsafeBytes {
$0.load(as: Double.self)
}
print(value) // 42.13
There is one problem with this approach: It requires that the memory is property aligned for the type (here: aligned to a 8-byte address). But that is not guaranteed, e.g. if the data was obtained as a slice of another Data value.
It is therefore safer to copy the bytes to the value:
let data = Data([0x71, 0x3d, 0x0a, 0xd7, 0xa3, 0x10, 0x45, 0x40])
var value = 0.0
let bytesCopied = withUnsafeMutableBytes(of: &value, { data.copyBytes(to: $0)} )
assert(bytesCopied == MemoryLayout.size(ofValue: value))
print(value) // 42.13
Explanation:
withUnsafeMutableBytes(of:_:) invokes the closure with a mutable buffer pointer covering the raw bytes of the value.
The copyBytes(to:) method of DataProtocol (to which Data conforms) copies bytes from the data to that buffer.
The return value of copyBytes() is the number of bytes copied. It is equal to the size of the destination buffer, or less if the data does not contain enough bytes.
Generic solution #1
The above conversions can now easily be implemented as generic methods of struct Data:
extension Data {
init<T>(from value: T) {
self = Swift.withUnsafeBytes(of: value) { Data($0) }
}
func to<T>(type: T.Type) -> T? where T: ExpressibleByIntegerLiteral {
var value: T = 0
guard count >= MemoryLayout.size(ofValue: value) else { return nil }
_ = Swift.withUnsafeMutableBytes(of: &value, { copyBytes(to: $0)} )
return value
}
}
The constraint T: ExpressibleByIntegerLiteral is added here so that we can easily initialize the value to “zero” – that is not really a restriction because this method can be used with “trival” (integer and floating point) types anyway, see below.
Example:
let value = 42.13 // implicit Double
let data = Data(from: value)
print(data as NSData) // <713d0ad7 a3104540>
if let roundtrip = data.to(type: Double.self) {
print(roundtrip) // 42.13
} else {
print("not enough data")
}
Similarly, you can convert arrays to Data and back:
extension Data {
init<T>(fromArray values: [T]) {
self = values.withUnsafeBytes { Data($0) }
}
func toArray<T>(type: T.Type) -> [T] where T: ExpressibleByIntegerLiteral {
var array = Array<T>(repeating: 0, count: self.count/MemoryLayout<T>.stride)
_ = array.withUnsafeMutableBytes { copyBytes(to: $0) }
return array
}
}
Example:
let value: [Int16] = [1, Int16.max, Int16.min]
let data = Data(fromArray: value)
print(data as NSData) // <0100ff7f 0080>
let roundtrip = data.toArray(type: Int16.self)
print(roundtrip) // [1, 32767, -32768]
Generic solution #2
The above approach has one disadvantage: It actually works only with "trivial"
types like integers and floating point types. "Complex" types like Array
and String have (hidden) pointers to the underlying storage and cannot be
passed around by just copying the struct itself. It also would not work with
reference types which are just pointers to the real object storage.
So solve that problem, one can
Define a protocol which defines the methods for converting to Data and back:
protocol DataConvertible {
init?(data: Data)
var data: Data { get }
}
Implement the conversions as default methods in a protocol extension:
extension DataConvertible where Self: ExpressibleByIntegerLiteral{
init?(data: Data) {
var value: Self = 0
guard data.count == MemoryLayout.size(ofValue: value) else { return nil }
_ = withUnsafeMutableBytes(of: &value, { data.copyBytes(to: $0)} )
self = value
}
var data: Data {
return withUnsafeBytes(of: self) { Data($0) }
}
}
I have chosen a failable initializer here which checks that the number of bytes provided
matches the size of the type.
And finally declare conformance to all types which can safely be converted to Data and back:
extension Int : DataConvertible { }
extension Float : DataConvertible { }
extension Double : DataConvertible { }
// add more types here ...
This makes the conversion even more elegant:
let value = 42.13
let data = value.data
print(data as NSData) // <713d0ad7 a3104540>
if let roundtrip = Double(data: data) {
print(roundtrip) // 42.13
}
The advantage of the second approach is that you cannot inadvertently do unsafe conversions. The disadvantage is that you have to list all "safe" types explicitly.
You could also implement the protocol for other types which require a non-trivial conversion, such as:
extension String: DataConvertible {
init?(data: Data) {
self.init(data: data, encoding: .utf8)
}
var data: Data {
// Note: a conversion to UTF-8 cannot fail.
return Data(self.utf8)
}
}
or implement the conversion methods in your own types to do whatever is
necessary so serialize and deserialize a value.
Byte order
No byte order conversion is done in the above methods, the data is always in
the host byte order. For a platform independent representation (e.g.
“big endian” aka “network” byte order), use the corresponding integer
properties resp. initializers. For example:
let value = 1000
let data = value.bigEndian.data
print(data as NSData) // <00000000 000003e8>
if let roundtrip = Int(data: data) {
print(Int(bigEndian: roundtrip)) // 1000
}
Of course this conversion can also be done generally, in the generic
conversion method.
You can get an unsafe pointer to mutable objects by using withUnsafePointer:
withUnsafePointer(&input) { /* $0 is your pointer */ }
I don't know of a way to get one for immutable objects, because the inout operator only works on mutable objects.
This is demonstrated in the answer that you've linked to.
In my case, Martin R's answer helped but the result was inverted. So I did a small change in his code:
extension UInt16 : DataConvertible {
init?(data: Data) {
guard data.count == MemoryLayout<UInt16>.size else {
return nil
}
self = data.withUnsafeBytes { $0.pointee }
}
var data: Data {
var value = CFSwapInt16HostToBig(self)//Acho que o padrao do IOS 'e LittleEndian, pois os bytes estavao ao contrario
return Data(buffer: UnsafeBufferPointer(start: &value, count: 1))
}
}
The problem is related with LittleEndian and BigEndian.
This question already has answers here:
How can I get a real IP address from DNS query in Swift?
(3 answers)
Closed 2 years ago.
I'm trying to do a simple DNS lookup in swift. So far, here is the code that I have:
let hostRef = CFHostCreateWithName(kCFAllocatorDefault, "google.com").takeRetainedValue()
var resolved = CFHostStartInfoResolution(hostRef, CFHostInfoType.Addresses, nil)
let addresses = CFHostGetAddressing(hostRef, &resolved).takeRetainedValue() as NSArray
At this point, each element in the "addresses" NSArray is a CFDataRef object wrapping a sockaddr struct.
Since CFDataRef can be toll-free bridged to NSData, I can loop through them like so:
for address: AnyObject in addresses {
println(address) // address is of type NSData.
}
So far so good (I think). This prints out valid looking data when I run it in a unit test. Here is where I get stuck though. For the life of me, I can't figure out how to convert the bytes in the NSData object into a sockaddr struct.
How can I convert address.bytes, which is of type COpaquePointer?, into a c struct? Any help appreciated. I'm banging my head against the wall trying to figure this out.
For a simpler solution using getnameinfo, see Martin's answer here: How can I get a real IP address from DNS query in Swift?
Updated for Swift 5 / IPv6:
The objects returned by CFHostGetAddressing can be bridged to Swift as Data, and cast to in_addr/in6_addr by using withUnsafeBytes and assumingMemoryBound(to:).
Here's a complete example that uses inet_ntop to convert IPv4/IPv6 addresses to strings:
import CFNetwork
import Foundation
protocol NetworkAddress {
static var family: Int32 { get }
static var maxStringLength: Int32 { get }
}
extension in_addr: NetworkAddress {
static let family = AF_INET
static let maxStringLength = INET_ADDRSTRLEN
}
extension in6_addr: NetworkAddress {
static let family = AF_INET6
static let maxStringLength = INET6_ADDRSTRLEN
}
extension String {
init<A: NetworkAddress>(address: A) {
// allocate a temporary buffer large enough to hold the string
var buf = ContiguousArray<Int8>(repeating: 0, count: Int(A.maxStringLength))
self = withUnsafePointer(to: address) { rawAddr in
buf.withUnsafeMutableBufferPointer {
String(cString: inet_ntop(A.family, rawAddr, $0.baseAddress, UInt32($0.count)))
}
}
}
}
func addressToString(data: Data) -> String? {
return data.withUnsafeBytes {
let family = $0.baseAddress!.assumingMemoryBound(to: sockaddr_storage.self).pointee.ss_family
// family determines which address type to cast to (IPv4 vs IPv6)
if family == numericCast(AF_INET) {
return String(address: $0.baseAddress!.assumingMemoryBound(to: sockaddr_in.self).pointee.sin_addr)
} else if family == numericCast(AF_INET6) {
return String(address: $0.baseAddress!.assumingMemoryBound(to: sockaddr_in6.self).pointee.sin6_addr)
}
return nil
}
}
let host = CFHostCreateWithName(kCFAllocatorDefault, "google.com" as CFString).takeRetainedValue()
var resolved = DarwinBoolean(CFHostStartInfoResolution(host, .addresses, nil))
let addresses = CFHostGetAddressing(host, &resolved)?.takeUnretainedValue() as! [Data]?
print(addresses?.compactMap(addressToString))
You can use the NSData method getBytes(_, length:) method and pass the sockaddr struct to the inout parameter using the prefix & operator:
var data: NSData ...
var address: sockaddr ...
data.getBytes(&address, length: MemoryLayout<sockaddr>.size)
Updated for Swift 3:
let host = CFHostCreateWithName(kCFAllocatorDefault, "google.com" as CFString).takeRetainedValue()
var resolved = DarwinBoolean(CFHostStartInfoResolution(host, .addresses, nil))
let addresses = CFHostGetAddressing(host, &resolved)?.takeUnretainedValue() as! [NSData]?
if let data = addresses?.first {
var storage = sockaddr_storage()
data.getBytes(&storage, length: MemoryLayout<sockaddr_storage>.size)
if Int32(storage.ss_family) == AF_INET {
let addr4 = withUnsafePointer(to: &storage) {
$0.withMemoryRebound(to: sockaddr_in.self, capacity: 1) {
$0.pointee
}
}
// prints 74.125.239.132
print(String(cString: inet_ntoa(addr4.sin_addr), encoding: .ascii))
}
}
Updated 6/3/2015:
Now that C structs can be easily zero-initialized, this becomes much simpler:
let host = CFHostCreateWithName(kCFAllocatorDefault, "google.com").takeRetainedValue()
var resolved = CFHostStartInfoResolution(host, .Addresses, nil)
let addresses = CFHostGetAddressing(host, &resolved)?.takeUnretainedValue() as! [NSData]?
if let data = addresses?.first {
var storage = sockaddr_storage()
data.getBytes(&storage, length: sizeof(sockaddr_storage))
if Int32(storage.ss_family) == AF_INET {
let addr4 = withUnsafePointer(&storage) { UnsafePointer<sockaddr_in>($0).memory }
// prints 74.125.239.132
println(String(CString: inet_ntoa(addr4.sin_addr), encoding: NSASCIIStringEncoding))
}
}
Unfortunately this requires sockaddr to be initialized first. To avoid that, you could do something like this:
func makeWithUnsafePointer<T>(body: UnsafePointer<T> -> ()) -> T {
let ptr = UnsafePointer<T>.alloc(sizeof(T))
body(ptr)
return ptr.move()
}
let addr: sockaddr = makeWithUnsafePointer {
data.getBytes($0 as UnsafePointer<sockaddr>, length: sizeof(sockaddr))
}
Or this:
func makeWithUninitialized<T>(body: inout T -> ()) -> T {
let ptr = UnsafePointer<T>.alloc(sizeof(T))
body(&ptr.memory)
return ptr.move()
}
let addr = makeWithUninitialized { (inout addr: sockaddr) in
data.getBytes(&addr, length: sizeof(sockaddr))
}
For more discussion, see Swift: Pass Uninitialized C Structure to Imported C function