Swift Array of strings to UnsafeMutablePointer<Unmanaged<CFString>>!

1k views Asked by At

I am trying to call DADiskMountWithArguments using Swift.

swiftfunc DADiskMountWithArguments(_ disk: DADisk, _ path: CFURL?, _ options: DADiskMountOptions, _ callback: DADiskMountCallback?, _ context: UnsafeMutableRawPointer?, _ arguments: UnsafeMutablePointer<Unmanaged<CFString>>!)

My issue is getting from a Swift array of strings, to an UnsafeMutablePointer<Unmanaged<CFString>>! which is the expected argument input format.

From the docs:

arguments
  The null-terminated list of mount options to pass to /sbin/mount -o.

In Objective-C I accomplished the same call by creating the arguments value like this:

NSArray *args = @[
            @"rdonly",
            @"noowners",
            @"nobrowse",
            @"-j",
        ];

CFStringRef *argv = calloc(args.count + 1, sizeof(CFStringRef));
CFArrayGetValues((__bridge CFArrayRef)args, CFRangeMake(0, (CFIndex)args.count), (const void **)argv);

DADiskMountWithArguments((DADiskRef)_disk, (__bridge CFURLRef)url, kDADiskMountOptionDefault, DiskMountCallback, (__bridge void *)(self), (CFStringRef *)argv);

But I have not successfully ported this method to Swift. And I haven't found a way to get the argument array into memory and getting the correct pointer to it either.

Things I've tried:

  1. Trying to use CFArrayGetValues:
// Example arguments array
let arguments = ["rdonly", "noowners", "nobrowse", "-j"]

// Create an UnsafeMutableRawPointer and allocate the correct string size
let argsUnsafeMutableRawPointer = calloc(arguments.count + 1, MemoryLayout<CFString>.size)

// Convert the Mutable pointer to an Immutable one
let argsUnsafeRawPointer: UnsafeRawPointer? = UnsafeRawPointer.init(argsUnsafeMutableRawPointer)

// CFArrayGetValues expects an UnsafeMutablePointer<UnsafeRawPointer?>. I have an UnsafeRawPointer, but can't get it into an UnsafeMutablePointer<T>.
let argsUnsafeMutablePointer: UnsafeMutablePointer<UnsafeRawPointer?>! = ?

// Call CFArrayGetValues
CFArrayGetValues(arguments as CFArray, CFRangeMake(0, CFIndex(arguments.count)), argsUnsafeMutablePointer)

// Call DADiskMountWithArguments
DADiskMountWithArguments(self.diskRef, url, DADiskMountOptions(kDADiskMountOptionDefault), diskMountCallback, nil, ?)

Should I use an Opaque pointer to bridge from UnsafeRawPointer to UnsafeMutablePointer?

  1. Trying to create the Array of c strings (char **) without CFArrayGetValues. But I don't really know how I would go about doing that?
// Example arguments array
let arguments = ["rdonly", "noowners", "nobrowse", "-j"]

// Create an Unmanaged<CFString> from the arguments array
let argsUnmanagedCFString: Unmanaged<CFString> = ?

// Create an UnsafeMutablePointer<Unmanaged<CFString>>! from the argsUnmanagedCFString
let argsUnsafeMutablePointer: UnsafeMutablePointer<Unmanaged<CFString>>! = ?

// Call DADiskMountWithArguments
DADiskMountWithArguments(self.diskRef, url, DADiskMountOptions(kDADiskMountOptionDefault), diskMountCallback, nil, argsUnsafeMutablePointer)

Is it again Opaque pointers that is the key to bridging the different types, or am I looking at this the wrong way?

Any help is greatly appreciated!

Thank you.

0

There are 0 answers