简体   繁体   中英

Correct syntax to unregister a callback in the DiskArbitration framework

I'm going to implement an observer to be notified when a specific volume disappeared.

The notifications in NSWorkspace are not an option, because I need a notification about device switched off rather than device unmounted .

Registering is pretty easy ( I left out the error handling)

var callbackSession : DASession?

let callbackSession = DASessionCreate(kCFAllocatorDefault)
DASessionSetDispatchQueue(callbackSession!, DispatchQueue.global())  
DARegisterDiskDisappearedCallback(callbackSession!, nil, volumeDidDisappearCallback, nil)

The callback closure is

let volumeDidDisappearCallback : DADiskDisappearedCallback = { (disk, context) in
   // do something with disk
}

The unregister method

func DAUnregisterCallback(_ session: DASession, _ callback: UnsafeMutableRawPointer, _ context: UnsafeMutableRawPointer?)

expects an generic UnsafeMutableRawPointer rather than one of the specific callback types.

When I pass the callback closure to the callback parameter I get

Cannot convert value of type 'DADiskDisappearedCallback' (aka '@convention(c) (DADisk, Optional) -> ()') to expected argument type 'UnsafeMutableRawPointer'

My question is: How can I convert the callback object volumeDidDisappearCallback to UnsafeMutableRawPointer ?

DADiskDisappearedCallback is defined as

public typealias DADiskDisappearedCallback = @convention(c) (DADisk, UnsafeMutableRawPointer?) -> Swift.Void

which is the Swift mapping of the C function pointer

typedef void (*DADiskAppearedCallback)(DADiskRef disk, void *context);

The unregister function is defined in C as

void DAUnregisterCallback(DASessionRef session, void *callback, void *context);

with a void *callback parameter, and in C you can pass the various kinds of callback function pointers ( DADiskAppearedCallback , DADiskDescriptionChangedCallback , ...) without casting.

In Swift you have to cast the function pointer to a void pointer explicitly:

let cb = unsafeBitCast(volumeDidDisappearCallback, to: UnsafeMutableRawPointer.self)
DAUnregisterCallback(callbackSession!, cb, nil)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM