如何在现代 OS X 版本上从 C 调用 objc_msgSend
How to call objc_msgSend from C on modern OS X versions
我需要从 C 对 OS X 上的 objc_msgSend 进行一些相对简单的调用。此代码用于工作 id event_data = objc_msgSend((id) objc_getClass("NSEvent"), sel_registerName("eventWithCGEvent:"), event_ref);
,但是,Apple 最近将函数签名更改为 void objc_msgSend(void);
来解决一些问题。普遍的共识是,这应该用函数指针来解决,但是,如果没有关于 "function called through a non-compatible type" 和 "if this code is reached, the program will abort." 的一些不祥警告,我无法让它工作 我的新函数指针实现看起来像 id event_data = ((id (*)(id, SEL, CGEventRef)) objc_msgSend)((id) objc_getClass("NSEvent"), sel_registerName("eventWithCGEvent:"), event_ref);
但我担心这些警告。 event_ref 变量是定义为 CGEventRef event_ref
的函数参数。有没有人有想法使这项工作?
你可以试试:
id (*eventWithCGEvent)(Class, SEL, CGEventRef) = (id (*)(Class, SEL, CGEventRef)) objc_msgSend;
这定义了一个名为 eventWithCGEvent
的函数指针,它具有三个参数:一个接收器(因为它是一个 class 方法,所以它是 Class
类型)、选择器和一个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;
}
我需要从 C 对 OS X 上的 objc_msgSend 进行一些相对简单的调用。此代码用于工作 id event_data = objc_msgSend((id) objc_getClass("NSEvent"), sel_registerName("eventWithCGEvent:"), event_ref);
,但是,Apple 最近将函数签名更改为 void objc_msgSend(void);
来解决一些问题。普遍的共识是,这应该用函数指针来解决,但是,如果没有关于 "function called through a non-compatible type" 和 "if this code is reached, the program will abort." 的一些不祥警告,我无法让它工作 我的新函数指针实现看起来像 id event_data = ((id (*)(id, SEL, CGEventRef)) objc_msgSend)((id) objc_getClass("NSEvent"), sel_registerName("eventWithCGEvent:"), event_ref);
但我担心这些警告。 event_ref 变量是定义为 CGEventRef event_ref
的函数参数。有没有人有想法使这项工作?
你可以试试:
id (*eventWithCGEvent)(Class, SEL, CGEventRef) = (id (*)(Class, SEL, CGEventRef)) objc_msgSend;
这定义了一个名为 eventWithCGEvent
的函数指针,它具有三个参数:一个接收器(因为它是一个 class 方法,所以它是 Class
类型)、选择器和一个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;
}