A Tyshka
A Tyshka

Reputation: 4100

Swift C interop: Passing Swift Argv to C argv

I am working on a swift wrapper for a C library. One such function in this library expects the command line arguments, in the form of char const *const *. This is linked to swift as Optional<UnsafePointer<UnsafePointer<Int8>?>> From swift I can obtain the command line arguments as CommandLine.unsafeArgv, of type UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>. How can I convert this to the expected immutable type? I know UnsafePointer has a constructor that takes an UnsafeMutablePointer, but I'm unsure of how to handle the nested types. Suggestions on how to correctly convert this?

Upvotes: 2

Views: 245

Answers (1)

Asperi
Asperi

Reputation: 257789

Try the following (tested with Xcode 12 / swift 5.3)

    let values: UnsafePointer<UnsafePointer<Int8>?> = 
        UnsafeRawPointer(CommandLine.unsafeArgv).bindMemory(
            to: UnsafePointer<Int8>?.self,
            capacity: Int(CommandLine.argc)
        )

    your_api_func(Int(CommandLine.argc), values)

Alternate: (on @MartinR comment) tested & worked as well.

    CommandLine.unsafeArgv.withMemoryRebound(
            to: UnsafePointer<Int8>?.self, 
            capacity: Int(CommandLine.argc)) { ptr in
        your_api_func(Int(CommandLine.argc), ptr)
    }

Upvotes: 1

Related Questions