I'd like to expose such structs in Swift. One way is by holding OpaquePointer, and the other is (I guess?) holding the pointers directly. I'm not aware of other options. If I hold the pointers directly, I was quite surprised to see the following compile without warning or error:
var b : ctype_B_handle
b = create_B()
consume_A(b)
Note that ctype_A and ctype_B are not void *, though it seems like Swift is type erasing them.
Is there a way to hold pointers to C types such that the above would fail to compile? Even C++ is safer with this sort of thing.
However, in my view this remains one of the most deeply unpleasant sharp edges of Swift.
I have two recommendations for how to deal with this. The first is to adopt the same strategy that I adopt with all wrappers around C: try to wrap these pointers at as low a level as possible in Swift types and don’t let them escape. Then, comment the code to say what the actual type of that pointer is and try to ensure you don’t get that wrong. This is brittle in the face of nasty little type changes in the C code, but those are usually rare.
The other option is to wrap these pointers in new, non-opaque C structs, and then redefine every function you want to call with a new thunk that takes your new structure and just extracts the pointer from it. This is profoundly silly, but it does return the type safety back in the Swift code, while allowing the C compiler to ensure you didn’t screw up. On the other hand, you now have to define these thunks for everything you want to do.
This will make a RawRepresentable wrapper type whenever that typedef is used. The downside, though, is that you can't differentiate between const and non-const pointers to the struct this way in the C code. There's not really a great answer here (given the current state of things).
Uh…sort of. If you look in the Swift branch of Clang at https://github.com/apple/llvm-project/tree/swift/master, you can find that the attributes are documented in the file clang/include/clang/Basic/AttrDocs.td, which is the form used to generate the list at Attributes in Clang — Clang 16.0.0git documentation. But since most of the Swift attributes aren't upstreamed to LLVM's Clang, they won't appear in the list on llvm.org, and I don't think Apple (or the Swift project) puts that list anywhere else. Even then, the documentation for swift_wrapper is woefully out of date (it's still using the original name swift_newtype, and the description is wrong).