outputting a value to a typedef pointer in swift

随声附和 提交于 2019-12-11 17:34:53

问题


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:

  • 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
  • As the error says, your 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)


来源:https://stackoverflow.com/questions/55840722/outputting-a-value-to-a-typedef-pointer-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!