Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare pointers to C functions in Swift

I'm looking for a way to compare pointers to c-functions. E.g.:

let firstHandler = NSGetUncaughtExceptionHandler()

NSSetUncaughtExceptionHandler(onUncaughtException)
let secondHandler = NSGetUncaughtExceptionHandler()

if firstHandler == secondHandler {
    debugPrint("equal")
}

Neighter ==, nor === works

In Objective C I could express this as follows:

NSUncaughtExceptionHandler *firstHandler = NSGetUncaughtExceptionHandler();

NSSetUncaughtExceptionHandler(onUncaughtException);
NSUncaughtExceptionHandler *secondHandler = NSGetUncaughtExceptionHandler();

if (firstHandler == secondHandler) {
    NSLog(@"equal");
}

Thanks in advance

like image 774
Tim Avatar asked Apr 28 '17 14:04

Tim


1 Answers

Generally, you cannot compare functions for equality in Swift. However, NSSetUncaughtExceptionHandler returns a

(@convention(c) (NSException) -> Swift.Void)?

i.e. a (optional) C-compatible function, and such a function can be forcefully converted to an (optional) raw pointer with unsafeBitCast:

let ptr1 = unsafeBitCast(firstHandler, to: Optional<UnsafeRawPointer>.self) 
let ptr2 = unsafeBitCast(secondHandler, to: Optional<UnsafeRawPointer>.self) 

which can then be compared for equality

if ptr1 == ptr2 { .. }

A self-contained example:

func exceptionHandler1(exception : NSException) { }

func exceptionHandler2(exception : NSException) { }

NSSetUncaughtExceptionHandler(exceptionHandler1)
let firstHandler = NSGetUncaughtExceptionHandler()
NSSetUncaughtExceptionHandler(exceptionHandler2)
let secondHandler = NSGetUncaughtExceptionHandler()

let ptr1 = unsafeBitCast(firstHandler, to: Optional<UnsafeRawPointer>.self) 
let ptr2 = unsafeBitCast(secondHandler, to: Optional<UnsafeRawPointer>.self) 

print(ptr1 == ptr2) // false
like image 195
Martin R Avatar answered Sep 22 '22 08:09

Martin R