再presenting空函数指针斯威夫特C函数 [英] Representing NULL Function Pointers to C Functions in Swift
问题描述
考虑私营尚未排序的详细记录可可的C函数 _NSLogCStringFunction()
和 _NSSetLogCStringFunction()
。 _NSLogCStringFunction()
返回一个函数指针,为使用背后的幕后的Objective-C运行C函数的NSLog()
和 _NSSetLogCStringFunction()
允许开发人员指定记录自己的C函数。在这两种功能的更多信息可以在发现这个堆栈溢出问题并的此的WebObjects支持文章。
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.
在C,我可以在一个空函数指针传递给 _NSSetLogCStringFunction()
:
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) -> ()')
如果我试图绕过这个编译时通过 unsafeBitCast
警告,我的程序刚刚与 EXC_BAD_INSTRUCTION
崩溃(如预期,因为签名是错误的):
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
我怎样重新present一个 NULL
函数指针(无效*)
或(无效(*)(为const char *,无符号,布尔))
/ (UnsafePointer&LT; INT8&gt;中UInt32的,布尔) - GT;虚空在斯威夫特
?
推荐答案
在(Objective-)C申报的雨燕映射
The Swift mapping of the (Objective-)C declaration
extern void _NSSetLogCStringFunction(void(*)(const char*, unsigned, BOOL));
是
public func _NSSetLogCStringFunction(_: (@convention(c) (UnsafePointer<Int8>, UInt32, ObjCBool) -> Void)!)
最简单的解决办法是把Objective-C的的extern
声明成一个Objective-C头文件,并包括
从桥接报头。
The easiest solution would be to put the Objective-C extern
declaration into an Objective-C header file and include that
from the bridging header.
替代地,在纯夫特它应
typealias NSLogCStringFunc = @convention(c) (UnsafePointer<Int8>, UInt32, ObjCBool) -> Void
@_silgen_name("_NSSetLogCStringFunction")
func _NSSetLogCStringFunction(_: NSLogCStringFunc!) -> Void
在任一情况下,该函数的参数是一个隐式展开可选
你可以用称之为零
。例如:
In either case, the function parameter is an implicitly unwrapped optional,
and you can call it with nil
. Example:
func myLogger(message: UnsafePointer<Int8>, _ length: UInt32, _ withSysLogBanner: ObjCBool) -> Void {
print(String(format:"myLogger: %s", message))
}
_NSSetLogCStringFunction(myLogger) // Set NSLog hook.
NSLog("foo")
_NSSetLogCStringFunction(nil) // Reset to default.
NSLog("bar")
输出:
myLogger: foo
2016-04-28 18:24:05.492 prog[29953:444704] bar
这篇关于再presenting空函数指针斯威夫特C函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!