Как вызвать objc_msgSend из C в современных версиях OS X - PullRequest
0 голосов
/ 02 апреля 2020

Мне нужно сделать несколько относительно простых вызовов objc_msgSend на OS X из C. Этот код используется для работы 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. У кого-нибудь есть идея сделать эту работу?

1 Ответ

1 голос
/ 03 апреля 2020

Вы можете попробовать:

id (*eventWithCGEvent)(Class, SEL, CGEventRef) = (id (*)(Class, SEL, CGEventRef)) objc_msgSend;

Это определяет указатель функции с именем eventWithCGEvent с тремя параметрами: получатель (так как это метод класса, он имеет тип 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...