[swift-users] Why does withUnsafePointer(to:) require a var argument?
Rien
Rien at Balancingrock.nl
Fri Apr 28 01:51:08 CDT 2017
You will need to take full control over allocation and deallocation.
Here is a piece of code from my project SwifterSockets (on github, see the link in my signature)
public func tipReceiverLoop(
socket: Int32,
bufferSize: Int,
duration: TimeInterval,
receiver: ReceiverProtocol?) {
...
// Allocate the data buffer
let buffer = UnsafeMutableRawPointer.allocate(bytes: bufferSize, alignedTo: 1)
// ===============================================================================
// This loop stays active as long as the consumer wants more and no error occured.
// ===============================================================================
var cont = true
repeat {
...
// ================================================
// Wait until select signals incoming data activity
// ================================================
let selres = waitForSelect(socket: socket, timeout: timeout, forRead: true, forWrite: false)
switch selres {
...
case .ready:
// =============
// Call the recv
// =============
let bytesRead = Darwin.recv(socket, buffer.assumingMemoryBound(to: UInt8.self), bufferSize, 0)
switch bytesRead {
...
case 1 ... Int.max: // Callback for the received data
cont = receiver?.receiverData(UnsafeBufferPointer<UInt8>(start: buffer.assumingMemoryBound(to: UInt8.self), count: bytesRead)) ?? true
... }
}
} while cont
// Deallocate the data buffer
buffer.deallocate(bytes: bufferSize, alignedTo: 1)
}
Regards,
Rien
Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl - A server for websites build in Swift
> On 28 Apr 2017, at 08:02, Rick Mann <rmann at latencyzero.com> wrote:
>
> Yeah, okay. So: how do I do this in a way that is safe?
>
> --
> Rick Mann
> rmann at latencyzero.com
>
>> On Apr 27, 2017, at 23:00, Rien <Rien at Balancingrock.nl> wrote:
>>
>> To address your question:
>>
>> https://developer.apple.com/reference/foundation/data/1779823-withunsafemutablebytes
>>
>> "Warning
>> The byte pointer argument should not be stored and used outside of the lifetime of the call to the closure."
>>
>> Which is exactly what you are doing, hence the code is unsafe (no pun intended).
>>
>> Regards,
>> Rien
>>
>> Site: http://balancingrock.nl
>> Blog: http://swiftrien.blogspot.com
>> Github: http://github.com/Balancingrock
>> Project: http://swiftfire.nl - A server for websites build in Swift
>>
>>
>>
>>
>>
>>
>>> On 28 Apr 2017, at 01:38, Rick Mann <rmann at latencyzero.com> wrote:
>>>
>>>
>>>> On Apr 27, 2017, at 01:48 , Alex Blewitt <alblue at apple.com> wrote:
>>>>
>>> ...
>>>
>>>> The let constant may not even be stored in a single place; if it's known to be constant it can be in-lined at the point of use and potentially unpacked and dead code elimination throw away the unused members, for example.
>>>>
>>>> If you want to pass in a let constant into the pointer, you can create a copy of it locally in a local variable and then use that instead. However this will be in the local scope, so the pointer isn't valid after it returns.
>>>
>>> Ah, so this brings up another issue, then. Many of the calls in the C library take a pointer to some memory and hang on to it, filling it in at a later point (they make network requests). I've been doing it like this, and it's been working, but I wonder if this is fragile:
>>>
>>> class
>>> MyClass
>>> {
>>> func
>>> execute()
>>> {
>>> self.dataBuffer = Data(count: kLGSImageDataSize)
>>> precondition(self.dataBuffer != nil, "Unable to allocate image buffer (\(kLGSImageDataSize) bytes)")
>>>
>>> var params = c_library_params_t()
>>> params.data_capacity = self.dataBuffer!.count
>>>
>>> self.dataBuffer?.withUnsafeMutableBytes
>>> { (inBuffer) -> Void in
>>> // This call returns immediately, but assumes
>>> // it can write to inBuffer later…
>>>
>>> self.request = c_library_call(¶ms, inBuffer)
>>> }
>>>
>>> if self.request == nil
>>> {
>>> // Error
>>> }
>>> }
>>>
>>> var dataBuffer: Data?
>>> }
>>>
>>>
>>> --
>>> Rick Mann
>>> rmann at latencyzero.com
>>>
>>>
>>
>
More information about the swift-users
mailing list