我需要从 C 对 OS X 上的 objc_msgSend 进行一些相对简单的调用。这段代码可以正常工作id event_data = objc_msgSend((id) objc_getClass("NSEvent"), sel_registerName("eventWithCGEvent:"), event_ref);
,但是,Apple 最近更改了函数签名void objc_msgSend(void);
以解决一些问题。普遍的共识是,这应该用函数指针来解决,但是,如果没有一些关于“通过不兼容类型调用的函数”和“如果达到此代码,程序将中止。” 我的新函数指针实现看起来像id event_data = ((id (*)(id, SEL, CGEventRef)) objc_msgSend)((id) objc_getClass("NSEvent"), sel_registerName("eventWithCGEvent:"), event_ref);
,但我担心警告。event_ref 变量是定义为的函数参数CGEventRef event_ref
。有没有人有做这项工作的想法?
问问题
93 次
1 回答
1
你可以试试:
id (*eventWithCGEvent)(Class, SEL, CGEventRef) = (id (*)(Class, SEL, CGEventRef)) objc_msgSend;
这定义了一个用三个参数调用的函数指针eventWithCGEvent
:一个接收器(因为它是一个类方法,它是 type Class
)、选择器和一个 type 参数CGEventRef
。
在更多的上下文中,它可能看起来像这样:
#import "objc/message.h"
#import <CoreFoundation/CoreFoundation.h>
#import <CoreGraphics/CoreGraphics.h>
int main(int argc, const char * argv[]) {
...
id (*eventWithCGEvent)(Class, SEL, CGEventRef) = (id (*)(Class, SEL, CGEventRef)) objc_msgSend;
CGEventRef event_ref = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)42, true);
Class NSEventClass = objc_getClass("NSEvent");
SEL eventWithCGEventSelector = sel_registerName("eventWithCGEvent:");
id event = eventWithCGEvent(NSEventClass, eventWithCGEventSelector, event_ref);
CFRelease(event_ref);
...
//do sth with event...
...
return 0;
}
于 2020-04-02T21:29:08.863 回答