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.