Consider the private-yet-sort-of-documented Cocoa C functions _NSLogCStringFunction()
and _NSSetLogCStringFunction()
. _NSLogCStringFunction()
returns a function pointer to the C function used by the Objective-C runtime behind-the-scenes for NSLog()
, and _NSSetLogCStringFunction()
allows developers to specify their own C function for logging. More information on both of these functions can be found in this Stack Overflow question and this WebObjects support article.
In C, I can pass in a NULL function pointer to _NSSetLogCStringFunction()
:
extern void _NSSetLogCStringFunction(void(*)(const char*, unsigned, BOOL));
_NSSetLogCStringFunction(NULL); // valid
However, I'm running into some issues when I try to do this in pure Swift:
/// Represents the C function signature used under-the-hood by NSLog
typealias NSLogCStringFunc = (UnsafePointer<Int8>, UInt32, Bool) -> Void
/// Sets the C function used by NSLog
@_silgen_name("_NSSetLogCStringFunction")
func _NSSetLogCStringFunction(_: NSLogCStringFunc) -> Void
_NSSetLogCStringFunction(nil) // Error: nil is not compatible with expected argument type 'NSLogCStringFunc' (aka '(UnsafePointer<Int8>, UInt32, Bool) -> ()')
If I try bypass this compile-time warning with unsafeBitCast
, my program just crashes with EXC_BAD_INSTRUCTION
(as expected, since the signature is wrong):
let nullPtr: UnsafePointer<Void> = nil
let nullFuncPtr = unsafeBitCast(nullPtr, NSLogCStringFunc.self)
_NSSetLogCStringFunction(nullFuncPtr) // crash
How do I represent a NULL
function pointer to (void *)
or (void(*)(const char *, unsigned, BOOL))
/(UnsafePointer<Int8>, UInt32, Bool) -> Void
in Swift?