Using Objective-C classes from C code

I know that you can use Objective-C code using objc_msgSend to, I suppose, manually run runtime Objective-C, however, when I run this code, I get errors that reference NSString (although I never use it), and also other un -used classes.

Errors from xcode

enter image description here

I have the Objective-C code above (commented out) that I am trying to "simulate."

#include <Foundation/Foundation.h> /*Added suggestion by answer, same errors*/ #include <AppKit/AppKit.h> int main() { // convert objective c into c code /* NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSInformationalAlertStyle]; [alert setMessageText:@"Hello World"]; [alert setInformativeText:@"Hello World"]; [alert runModal]; */ id alert = objc_msgSend(objc_msgSend(objc_getClass("NSAlert"), sel_registerName("alloc")), sel_registerName("init")); objc_msgSend(alert, sel_getUid("setAlertStyle:"), NSInformationalAlertStyle); objc_msgSend(alert, sel_getUid("setMessageText:"), CFSTR("Hello World!")); objc_msgSend(alert, sel_getUid("setInformativeText:"), CFSTR("Hello World!")); objc_msgSend(alert, sel_getUid("runModal")); } 
+4
source share
1 answer

You are missing an import.

objc_msgSend declared in <objc/message.h> .

objc_getClass declared in <objc/runtime.h> .

sel_getUid and sel_registerName declared in <objc/objc.h> .

Now, given that <objc/objc.h> has already been imported <objc/runtime.h> , importing the latter along with <objc/message.h > should be sufficient.

I tested it in the following example and it works as expected

 #include <CoreFoundation/CoreFoundation.h> // Needed for CFSTR #include <objc/runtime.h> #include <objc/message.h> int main(int argc, char *argv[]) { id alert = (id (*)(id, SEL))objc_msgSend((id (*)(id, SEL))objc_msgSend(objc_getClass("NSAlert"), sel_registerName("alloc")), sel_registerName("init")); (void (*)(id, SEL, int))objc_msgSend(alert, sel_getUid("setAlertStyle:"), 1); // NSInformationalAlertStyle is defined in AppKit, so let just use 1 (void (*)(id, SEL, id))objc_msgSend(alert, sel_getUid("setMessageText:"), CFSTR("Hello World!")); (void (*)(id, SEL, id))objc_msgSend(alert, sel_getUid("setInformativeText:"), CFSTR("Hello World!")); (int (*)(id, SEL))objc_msgSend(alert, sel_getUid("runModal")); } 

Note

I added an explicit cast to objc_msgSend , as suggested by Greg Parker in the comments.

+5
source

Source: https://habr.com/ru/post/1501208/


All Articles