Home > Mobile >  Why I cannot include AppKit in pure C, even though I can declare the functions myself?
Why I cannot include AppKit in pure C, even though I can declare the functions myself?

Time:09-18

I would like to write a MacOS application using more C and less ObjC and Swift. I started by creating a main.c file with the main function. Next is to call NSApplicationMain from the main function. This is defined in AppKit. However, I get a Could not build module 'AppKit' error when I try #include <AppKit/AppKit.h> from main.c. I circumvented this with:

extern int NSApplicationMain(int argc, const char * _Nonnull *argv);

This worked. My question is, clearly NSApplicationMain can be called from C so why do I have to extern it directly instead of including AppKit.h directly? Why they do not let you include it the proper way instead of declaring NSApplicationMain yourself? Am I not supposed to do that?

Why can you not do this:

#include <stdio.h>
#include <AppKit/AppKit.h>
int main(int argc, const char *argv[]) {
    return NSApplicationMain(argc, argv);
}

But you can do this:

#include <stdio.h>
extern int NSApplicationMain(int argc, const char * _Nonnull *argv);
int main(int argc, const char *argv[]) {
    return NSApplicationMain(argc, argv);
}

CodePudding user response:

In short, it is not standard C header file though it has .h extension. Note, that even in Objective-C .m files AppKit.h must be imported not included

#import <AppKit/AppKit.h>

CodePudding user response:

I'm not an authority on this, but my take would be: AppKit is an Objective-C framework. It therefore has a header file that is written in Objective-C, and that can't be included in C. When you declare an AppKit function in C and call it, you are basically relying on the fact that the ABI – the internal calling conventions of registers, stack usage, etc. – are the same between both languages, and so it works (and I'm not actually certain that the ABI is 100% the same, although I think it is); but technically, you are calling an Objective-C function from C. There's no particular reason why Apple ought to bend over backwards to make that easy; programming in pure C is not common any more. If you really want to do this, you could always just make your C source file be a .m (Objective-C) file but limit yourself to only pure C language features. That will let you include the header, while letting you write "C" code (actually Objective-C, limited to the C subset of the language). Seems like a good solution to me.

  • Related