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:
- 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?
- 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.