如何将CFunctionPointer转换为EventHandlerUPP?

时间:2015-03-08 23:31:49

标签: swift callback event-handling

我有一个名为 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 )

尝试构建此操作失败,并显示以下错误:

  

架构x86_64的未定义符号:

     

&#34; _Foo_C_Func&#34;,引自:

     Demo.o中的

__ TTOFSC10Foo_C_FuncFTVSs14COpaquePointerS_GVSs20UnsafeMutablePointerT___VSs5Int32

     

&#34; _NewEventHandlerUPP&#34;,引自:

     Demo.o中的

__ TFC17DemocfMS0_FT_S0_

     

ld:找不到架构x86_64的符号

我还注意到当我将鼠标悬停在最后一行上时,Xcode工具提示显示 NewEventHandlerUpp 的返回类型为(EventHandlerProcPtr)而不是 EventHandlerProcPtr < /强>

我做错了,还是不可能在Swift中创建 EventHandlerUPP

2 个答案:

答案 0 :(得分:3)

我正在为用户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 )

答案 1 :(得分:2)

如果您使用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 
)

请注意,我们可以使用“&amp;”为了避免现在手动分配指针,请注意,遵守非正式的“EventHandlerUPP”协议现在是显式的,并且不需要我们手动声明每个参数的类型。更容易阅读:)