Trouble assigning an array of C pointers to a C struct field


(Jens Alfke) #1

I’m bridging a C API (that I wrote) to Swift; I’ve got most of it together, but I’m stuck on one part, where I can’t get the bridging code to compile without errors no matter how I write it.

The basic problem is I’ve got a dynamically-allocated opaque C pointer type (C4Key*), and there’s a struct in the C API with a field that points to a C array of these, plus a count. In Swift I have an array of these pointers, typed as [COpaquePointer], and I want to point the struct field to it.

Here’s the relevant bit of the C API:

    typedef struct c4Key C4Key; // opaque type

    C4Key* c4key_new(void);

    typedef struct {
        // ...
        const C4Key **keys;
        size_t keysCount;
    } C4QueryOptions;

In my Swift code I have:

        var opt = C4QueryOptions()
        var keyHandles: [COpaquePointer] = wrappedKeys.map {$0.handle}
        // Attempt 1, error is “Cannot assign [COpaquePointer] to COpaquePointer”:
        opt.keys = &keyHandles
        // Attempt 2, error is "cannot assign value of type 'UnsafePointer<[COpaquePointer]>' (aka 'UnsafePointer<Array<COpaquePointer>>') to type 'UnsafeMutablePointer<COpaquePointer>'"
        withUnsafePointer(&keyHandles) { keysPtr in
            opt.keys = keysPtr
            DoSomethingWith(opt)
        }

It’s definitely a type-checking problem; I can’t convince the compiler to give me a pointer to the elements of the array as a COpaquePointer. Any clues?

—Jens


(Jens Alfke) #2

The rubber-duckie effect strikes again! A few minutes after posting about my problem I figured out the answer:

        withUnsafeMutablePointer(&keyHandles[0]) { keysPtr in
            opt.keys = keysPtr
            DoSomethingWith(opt)
        }

—Jens