如何将 CFunctionPointer 转换为 EventHandlerUPP?
How to convert a CFunctionPointer to an EventHandlerUPP?
我有一个名为 Foo_C_Func 的 C 函数,我需要将其用作回调。该应用程序的其余部分在 Swift 中编码。据我了解,以下代码 应该 可以工作,但我却收到编译器错误。
// typealias makes our function signature easier to read
typealias Sig = ( EventHandlerCallRef, EventRef, UnsafeMutablePointer<Void>) -> OSStatus
// We need to make a CFunctionPointer to the C function
var ptr = UnsafeMutablePointer<Sig>.alloc(1)
ptr.initialize( Foo_C_Func )
let c_ptr = COpaquePointer( ptr )
let proc_ptr = CFunctionPointer<Sig>( c_ptr ) as EventHandlerProcPtr
// now we should be able to create the EventHandlerUPP
let handler_upp = NewEventHandlerUPP( proc_ptr )
尝试构建失败并出现以下错误:
Undefined symbols for architecture x86_64:
"_Foo_C_Func", referenced from:
__TTOFSC10Foo_C_FuncFTVSs14COpaquePointerS_GVSs20UnsafeMutablePointerT___VSs5Int32 in Demo.o
"_NewEventHandlerUPP", referenced from:
__TFC17DemocfMS0_FT_S0_ in Demo.o
ld: symbol(s) not found for architecture x86_64
我还注意到,当我将鼠标悬停在最后一行时,Xcode 工具提示显示 NewEventHandlerUpp 的 return 类型为 (EventHandlerProcPtr) 而不是 EventHandlerProcPtr.
我做错了吗,还是无法在 Swift 内创建 EventHandlerUPP?
我为用户 MAH 发布了这个,尽管我已经放弃了原来的项目。以下代码在 Swift 3 中编译。我还没有检查它是否可以超出此范围。
import Carbon
func hotkey_callback( _:EventHandlerCallRef?, _ event:EventRef?, _ context:UnsafeMutablePointer<Void>? ) -> OSStatus {
// Do stuff
return noErr
}
let handler_ref_ptr = UnsafeMutablePointer<EventHandlerRef?>( allocatingCapacity: 1 )
let spec_ptr = UnsafeMutablePointer<EventTypeSpec>( allocatingCapacity: 1 )
spec_ptr.pointee = EventTypeSpec( eventClass: OSType( kEventClassKeyboard ), eventKind: UInt32( kEventHotKeyPressed ) )
let hotkey_callback_pointer = hotkey_callback as! EventHandlerUPP
let status = InstallEventHandler( GetEventDispatcherTarget(), hotkey_callback_pointer, 1, spec_ptr, nil, handler_ref_ptr )
如果您使用的是 Swift 3,这里有一个替代答案。Swift 2 与 Swift 3 不同,前者很糟糕,而后者可用。
let hotkey_callback: EventHandlerUPP = { _, _, _ in
// Do stuff
return noErr
}
var handler: EventHandlerRef? = nil
var spec = EventTypeSpec(
eventClass: OSType(kEventClassKeyboard), eventKind: UInt32(kEventHotKeyPressed)
)
let status = InstallEventHandler(
GetEventDispatcherTarget(), hotkey_callback, 1, &spec, nil, &handler
)
请注意,我们现在可以使用“&”来避免手动分配指针,并注意遵守非正式的 "EventHandlerUPP" 协议现在是明确的,不需要我们手动声明每个参数的类型。阅读起来容易多了:)
我有一个名为 Foo_C_Func 的 C 函数,我需要将其用作回调。该应用程序的其余部分在 Swift 中编码。据我了解,以下代码 应该 可以工作,但我却收到编译器错误。
// typealias makes our function signature easier to read
typealias Sig = ( EventHandlerCallRef, EventRef, UnsafeMutablePointer<Void>) -> OSStatus
// We need to make a CFunctionPointer to the C function
var ptr = UnsafeMutablePointer<Sig>.alloc(1)
ptr.initialize( Foo_C_Func )
let c_ptr = COpaquePointer( ptr )
let proc_ptr = CFunctionPointer<Sig>( c_ptr ) as EventHandlerProcPtr
// now we should be able to create the EventHandlerUPP
let handler_upp = NewEventHandlerUPP( proc_ptr )
尝试构建失败并出现以下错误:
Undefined symbols for architecture x86_64:
"_Foo_C_Func", referenced from:
__TTOFSC10Foo_C_FuncFTVSs14COpaquePointerS_GVSs20UnsafeMutablePointerT___VSs5Int32 in Demo.o
"_NewEventHandlerUPP", referenced from:
__TFC17DemocfMS0_FT_S0_ in Demo.o
ld: symbol(s) not found for architecture x86_64
我还注意到,当我将鼠标悬停在最后一行时,Xcode 工具提示显示 NewEventHandlerUpp 的 return 类型为 (EventHandlerProcPtr) 而不是 EventHandlerProcPtr.
我做错了吗,还是无法在 Swift 内创建 EventHandlerUPP?
我为用户 MAH 发布了这个,尽管我已经放弃了原来的项目。以下代码在 Swift 3 中编译。我还没有检查它是否可以超出此范围。
import Carbon
func hotkey_callback( _:EventHandlerCallRef?, _ event:EventRef?, _ context:UnsafeMutablePointer<Void>? ) -> OSStatus {
// Do stuff
return noErr
}
let handler_ref_ptr = UnsafeMutablePointer<EventHandlerRef?>( allocatingCapacity: 1 )
let spec_ptr = UnsafeMutablePointer<EventTypeSpec>( allocatingCapacity: 1 )
spec_ptr.pointee = EventTypeSpec( eventClass: OSType( kEventClassKeyboard ), eventKind: UInt32( kEventHotKeyPressed ) )
let hotkey_callback_pointer = hotkey_callback as! EventHandlerUPP
let status = InstallEventHandler( GetEventDispatcherTarget(), hotkey_callback_pointer, 1, spec_ptr, nil, handler_ref_ptr )
如果您使用的是 Swift 3,这里有一个替代答案。Swift 2 与 Swift 3 不同,前者很糟糕,而后者可用。
let hotkey_callback: EventHandlerUPP = { _, _, _ in
// Do stuff
return noErr
}
var handler: EventHandlerRef? = nil
var spec = EventTypeSpec(
eventClass: OSType(kEventClassKeyboard), eventKind: UInt32(kEventHotKeyPressed)
)
let status = InstallEventHandler(
GetEventDispatcherTarget(), hotkey_callback, 1, &spec, nil, &handler
)
请注意,我们现在可以使用“&”来避免手动分配指针,并注意遵守非正式的 "EventHandlerUPP" 协议现在是明确的,不需要我们手动声明每个参数的类型。阅读起来容易多了:)