Swift 3 UnsafeMutablePointer initialization for C type float**
Asked Answered
S

1

0

Within Swift 3, I need to send data to a C object accepting float ** input.

In Swift 2, I used to declare a UnsafeMutablePointer< UnsafeMutablePointer<Float32>>, construct a swift Array (only for init!), and pass this to the pointer, and it worked:

    var bufferOut: UnsafeMutablePointer< UnsafeMutablePointer<Float32>>?
    arrayOut = Array(repeating: Array(repeating: 0, count: Int(size1), count: Int(size2))
    bufferOut = UnsafeMutablePointer< UnsafeMutablePointer<Float32>>(arrayOut)

This is all broken now in Swift 3!

  • What is the most Swifty way to pass a C-Style float** and initialize it?
  • What would be the best way to assign values in a UnsafeMutablePointer< UnsafeMutablePointer<T>>?

Documentations say that for T ** one should use AutoreleasingUnsafeMutablePointer<T> but I actually never managed to construct one!

Note that I don't actually care for the Array in the above example! If I could just initialize the Pointer directly using known capacities, I would.

Note: The Expected use cases Section of UnsafeRawPointer describes useful situations such C array and C Buffers, however translating such methods for the above construct is not evident!

Septuagesima answered 19/10, 2016 at 10:7 Comment(0)
S
2

Here is what I ended up doing and is working. It follows recommendations from new UnsafeMuTablePointer Reference showing example programs on simple schemes. In summary, it is required to allocate and assign each slot starting from top-level!

So in order to construct an UnsafeMutablePointer< UnsafeMutablePointer<T>> of size (size1, size2) (like a matrix), you can go ahead as follows using an intermediate vector here called vectorBuf:

    var vectorBuf : UnsafeMutablePointer<T>?
    vectorBuf = UnsafeMutablePointer<T>.allocate(capacity: size2)
    for index in 0...(size2) {     // had Int(channelCount)*
        vectorBuf!.advanced(by: index).pointee = 0.0
    }

    /// This is where allocation and initialization happens:
    bufferOut = UnsafeMutablePointer< UnsafeMutablePointer<T>?>.allocate(capacity: Int(size1))
    for index in 0...Int(size1) {
        bufferOut!.advanced(by: index).pointee = UnsafeMutablePointer<T>.allocate(capacity: (size2) )
        bufferOut!.advanced(by: index).pointee?.assign(from: vectorBuf!, count: size2)
    }

Hope this can be useful to others trying to use swift with signal processing calls in C/C++!

Septuagesima answered 19/10, 2016 at 15:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.