问题
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?
回答1:
Some observations:
TESTHANDLEappears to be an alias forUnsafeMutableRawPointer&testHandleis taking a reference (a pointer to the location) of thetestHandle, producing a value of typeinout UnsafeMutableRawPointer- As the error says, your
TestInitfunction takes a variable of typeUnsafeMutablePointer<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)
来源:https://stackoverflow.com/questions/55840722/outputting-a-value-to-a-typedef-pointer-in-swift