From working on SwiftNIO and Swift Crypto I've built up a list of best-practices that might be worth thinking about. I'll put my answers below. Note that this is not authoritative and I can't claim that this is what the community wants to do, but I think I've got more experience here than most.
You should hide it in a Swift type. In general, exposing the types of your dependencies isn't great. Wrapping the C types in Swift types gives you a type that is in your namespace and that you control, which makes it easier to (for example) add conformances to helpful Swift protocols.
This does force you to write more code than you otherwise would, but the advantage is that you can promise your types will behave in a Swifty way. This also allows you to reference count non-trivial C types to manage their lifetimes.
As an example, consider Swift Crypto's ArbitraryPrecisionInteger, a wrapper around BoringSSL's BIGNUM. This is a complex wrapper that provides lots of helper functionality (ExpressibleByIntegerLiteral, Equatable, Comparable, AdditiveArithmetic, Numeric, SignedNumeric, CustomDebugStringConvertible). It also takes a fundamentally referential type and turns it into a value type, making it much nicer to work with in Swift. (More on this later.)
Even there I'm missing some useful protocols: I could have given this a BinaryInteger conformance, too. I was just too lazy.
Wrap it in a Collection type that wraps the underlying pointer. If the pointer has a length this can be a RandomAccessCollection, otherwise it's a Collection. This avoids the need to copy, while giving you most of the friendliness you want from Arrays. In general when you think you want an Array what you actually want is something that can do what Array can do (be looped over, fast indexing, etc.): RandomAccessCollection is that.
An example of this is swift-nio-ssl's SSLConnection.PeerCertificateChainBuffers. This type provides access to the certificates provided by the peer in a TLS connection. This type is a RandomAccessCollection, which means it can be used essentially anywhere an Array can, but doesn't need a copy.
Wrap it in a class.
Any time you have an object that needs lifetime management being brought into Swift, the only way to safely manage that lifetime is to use the wrapper object in a class. In most cases you want value semantics for these things though, so you often need to then wrap that class wrapper in a struct to re-establish value semantics.
Again, Swift Crypto's ArbitraryPrecisionInteger is an example of this. It uses the CoW pattern along with a backing class that owns the C struct's lifetime. The need to involve an extra heap allocation here is a bit frustrating, but in many cases that heap allocation can be elided for objects that don't live long.
I recommend not bothering to use apinotes: writing a proper Swift wrapper will likely be better in the long-run.