【发布时间】:2016-04-28 13:52:11
【问题描述】:
考虑私有但排序的 Cocoa C 函数 _NSLogCStringFunction() 和 _NSSetLogCStringFunction()。 _NSLogCStringFunction() 为 NSLog() 返回一个指向 Objective-C 运行时幕后使用的 C 函数的函数指针,_NSSetLogCStringFunction() 允许开发人员指定自己的 C 函数进行日志记录。关于这两个函数的更多信息可以在this Stack Overflow question和this WebObjects support article找到。
在 C 中,我可以传入一个指向 _NSSetLogCStringFunction() 的 NULL 函数指针:
extern void _NSSetLogCStringFunction(void(*)(const char*, unsigned, BOOL));
_NSSetLogCStringFunction(NULL); // valid
但是,当我尝试在纯 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) -> ()')
如果我尝试用unsafeBitCast 绕过这个编译时警告,我的程序就会因为EXC_BAD_INSTRUCTION 而崩溃(正如预期的那样,因为签名错误):
let nullPtr: UnsafePointer<Void> = nil
let nullFuncPtr = unsafeBitCast(nullPtr, NSLogCStringFunc.self)
_NSSetLogCStringFunction(nullFuncPtr) // crash
如何在 Swift 中将 NULL 函数指针表示为 (void *) 或 (void(*)(const char *, unsigned, BOOL))/(UnsafePointer<Int8>, UInt32, Bool) -> Void?
【问题讨论】:
-
大声笑,无论出于何种原因立即投反对票 - 甚至没有时间阅读整个问题。
-
@luk2302 猜猜我有一个粉丝 :) 这对我来说是一个新纪录,44 秒内 -1。
标签: c swift function-pointers iphone-privateapi