I'm almost certain the title of this isn't correct but here goes...
I'm bridging to an Objective-C class to set a typedef. The bridge is set up and I'm able to declare the typedef var correctly.
In Objective-C I also called a method from the same class that, when called, output a value to the variable TestHandle.
var TestHandle : TESTHANDLE
TestInit(&TestHandle)
When I try this using Swift 5 I get this error:
Cannot convert value of type 'inout TESTHANDLE' (aka 'inout UnsafeMutableRawPointer') to expected argument type 'UnsafeMutablePointer<TESTHANDLE?>?' (aka 'Optional<UnsafeMutablePointer<Optional<UnsafeMutableRawPointer>>>')
Any pointers?
Some observations:
TESTHANDLE
appears to be an alias for UnsafeMutableRawPointer
&testHandle
is taking a reference (a pointer to the location) of the testHandle
, producing a value of type inout UnsafeMutableRawPointer
TestInit
function takes a variable of type UnsafeMutablePointer<TESTHANDLE?>?
, a.k.a. Optional<UnsafeMutablePointer<Optional<UnsafeMutableRawPointer>>>
Swift has some rules about how &
automatically bridges to the various pointer types, but to be frank, I don't understand them very well.
As far as I know, the Swift pointer types cannot represent nil (0x000...000). To do that, they need to be wrapped within an optional. So when you see the type
Optional<UnsafeMutablePointer<Optional<UnsafeMutableRawPointer>>>
It's actually two "semantic" parts:
Optional<UnsafeMutablePointer< Optional<UnsafeMutableRawPointer> >>
↳ A nullable pointer to ... ↳ ... something that's a nullable pointer of unspecified (void) type
The reason you're getting your error is because &testHandle
can only bridge your UnsafeMutableRawPointer
to a Optional<UnsafeMutablePointer<UnsafeMutableRawPointer>>
, but not the required Optional<UnsafeMutablePointer<Optional<UnsafeMutableRawPointer>>>
(the difference is in that missing layer of "inner" nullability). To get around this, make your testHandle
optional, yourself:
var testHandle: TESTHANDLE? // a.k.a. Optional<TESTHANDLE>, a.k.a. Optional< UnsafeMutableRawPointer>
Then, when you use the &
operator, Swift will wrap your value in the required Optional<UnsafeMutablePointer< ... >>
outter layer.
typealias TESTHANDLE = UnsafeMutableRawPointer
func testInit(_ p: UnsafeMutablePointer<TESTHANDLE?>?) {
print("Success!")
}
var testHandle: TESTHANDLE? = nil
testInit(&testHandle)