Swift 3中的UnsafeMutablePointer到期望的参数类型UnsafeMutablePointer <_>

gle*_*rey 4 macos cocoa swift receigen swift3

main.swift文件中,我们调用了收据检查系统(由Receigen生成).在Swift 2中,main.swift阅读:

startup(Process.argc, UnsafeMutablePointer<UnsafePointer<Int8>>(Process.unsafeArgv))
Run Code Online (Sandbox Code Playgroud)

升级到Swift 3后,我已经达到了:

startup(CommandLine.argc, UnsafeMutablePointer<UnsafePointer<Int8>>(CommandLine.unsafeArgv))
Run Code Online (Sandbox Code Playgroud)

显示错误:

无法将类型UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>(aka UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>)的值转换 为预期的参数类型UnsafeMutablePointer<_>

更新:使用链接的问题,使其显示为:

startup(CommandLine.argc, UnsafeMutableRawPointer(CommandLine.unsafeArgv)
    .bindMemory(
        to: UnsafeMutablePointer<Int8>.self,
        capacity: Int(CommandLine.argc)))
Run Code Online (Sandbox Code Playgroud)

生产:

无法将类型的值转换UnsafeMutablePointer<Int8>.Type为预期的参数类型UnsafePointer<Int8>?.Type(aka Optional<UnsafePointer<Int8>>.Type)

编译器所指的位置to:UnsafeMutablePointer.

启动标题如下:

int startup(int argc, const char * argv[]);
Run Code Online (Sandbox Code Playgroud)

如何成功将变量传递给启动main.swift

mat*_*att 7

基本上,这是这里讨论的问题的变体:

Xcode 8 beta 6:main.swift无法编译

问题是CommandLine.unsafeArgv您的C函数所期望的类型和类型之间的阻抗不匹配.并且你不能仅仅通过从一个可变指针类型强制转换到另一个指针类型来抛弃这种不匹配.相反,您必须通过调用将其从一种类型转换为另一种类型bindMemory.并且要求a的错误消息Optional<UnsafePointer<Int8>>.Type告诉您要转向的类型:

    startup(
        CommandLine.argc,
        UnsafeMutableRawPointer(CommandLine.unsafeArgv)
            .bindMemory(
                to: Optional<UnsafePointer<Int8>>.self,
                capacity: Int(CommandLine.argc))
    )
Run Code Online (Sandbox Code Playgroud)

这应该允许你编译.在我的机器上使用存根测试startup,它实际上运行.但是,无论它是否会在您的机器上运行,以及它是否安全,都是有人猜的!这个东西无可否认令人抓狂......

编辑问题CommandLine.unsafeArgv在iOS 12/Xcode 10中得到修复,因此可能也解决了这个问题.