I have a C function
void myfunc(const void *ptr);
which is imported to Swift as
func myfunc(_ ptr: UnsafeRawPointer!)
This compiles and runs without problems:
let data = Data(bytes: [1, 2, 3, 4])
data.withUnsafeBytes { (ptr) in myfunc(ptr) } // (A)
and the type of `ptr` is inferred as `UnsafePointer<Void>`. But adding an explicit type
annotation produces a compiler warning:
data.withUnsafeBytes { (ptr: UnsafePointer<Void>) in myfunc(ptr) } // (B)
// warning: UnsafePointer<Void> has been replaced by UnsafeRawPointer
which is understandable in the view of "SE-0107 UnsafeRawPointer API".
The "Fix-it" replaces `UnsafePointer<Void>` by `UnsafeRawPointer`, and that does not
compile anymore:
data.withUnsafeBytes { (ptr: UnsafeRawPointer) in myfunc(ptr) } // (C)
// error: cannot convert value of type 'Void' to closure result type '_'
because there is no `withUnsafeBytes()` method taking a `(UnsafeRawPointer)->ResultType`
closure.
My questions are:
1. Why are (A) and (B) treated differently?
2. Is (A) "legal", or should one use some non-void pointer
data.withUnsafeBytes { (ptr: UnsafePointer<Int8>) in myfunc(ptr) } // (D)
(which feels wrong to me because it is converted back to a void pointer when
calling the function).
3. Or should there be a `withUnsafeRawPointer()` method which makes (C) compile as
data.withUnsafeRawBytes { (ptr: UnsafeRawPointer) in myfunc(ptr) }
This would also allow to access the data at byte offsets more easily, e.g.
data.withUnsafeRawBytes { ptr in
let u16 = ptr.load(fromByteOffset: 4, as: UInt16.self)
}
Does that makes sense?
Regards, Martin