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

UnsafeMutablePointer to expected argument type UnsafeMutablePointer<_> in Swift 3

main.swift 文件中,我们调用了我们的收据检查系统(由 Receigen 生成)。在Swift2中,main.swift读作:

startup(Process.argc, UnsafeMutablePointer<UnsafePointer<Int8>>(Process.unsafeArgv))

升级到Swift 3后,我得到了:

startup(CommandLine.argc, UnsafeMutablePointer<UnsafePointer<Int8>>(CommandLine.unsafeArgv))

显示错误:

Cannot convert value of type UnsafeMutablePointer<UnsafeMutablePointer<Int8>?> (aka UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) to expected argument type UnsafeMutablePointer<_>

更新:使用 使其显示为:

startup(CommandLine.argc, UnsafeMutableRawPointer(CommandLine.unsafeArgv)
    .bindMemory(
        to: UnsafeMutablePointer<Int8>.self,
        capacity: Int(CommandLine.argc)))

产生:

Cannot convert value of type UnsafeMutablePointer<Int8>.Type to expected argument type UnsafePointer<Int8>?.Type (aka Optional<UnsafePointer<Int8>>.Type)

编译器指的是to:UnsafeMutablePointer

启动的 header 看起来像:

int startup(int argc, const char * argv[]);

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

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

问题是 CommandLine.unsafeArgv 的类型与 C 函数期望的类型之间存在阻抗不匹配。并且您不能再仅仅通过从一种可变指针类型强制转换为另一种可变指针类型来消除这种不匹配。相反,您必须通过调用 bindMemory 从一种类型转向另一种类型(实际上)。错误消息要求 Optional<UnsafePointer<Int8>>.Type,告诉您要转向的类型:

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

那应该可以让你编译。在我的机器上用 startup 的存根进行测试,它实际上是 运行s。但是它是否会 运行 在你的机器上,它是否安全,是任何人的猜测!这东西无疑是令人抓狂的...

EDIT CommandLine.unsafeArgv 的问题已在 iOS 12 / Xcode 10 中修复,因此可能是此问题已修复也是。