Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
A simple implementation of a NSApplicationDelegate and two methods (openFile:, openFiles:) in pure C.
1. Compile and link with:
$ clang -g -o AppInC app_delegate.c -lobjc -framework Foundation -framework AppKit -isysroot /Applications/
2. Create a Info.plist with:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">
3. Make a "real" MacOS app of it:
$ mkdir -p
$ cp AppInC
$ cp Info.plist
4. Try to open a Lua file with the, it should display an alertbox with the path of the Lua file.
#include <stdio.h>
#include <stdlib.h>
#include <objc/runtime.h>
#include <objc/message.h>
#define ALLOC_INIT_OBJC_CLASS(class_name) objc_msgSend(objc_msgSend((id)objc_getClass(class_name), sel_getUid("alloc")), sel_getUid("init"));
extern id NSApp;
struct AppDel
Class isa;
// This is a strong reference to the class of the AppDelegate
// (same as [AppDelegate class])
Class AppDelClass;
BOOL AppDel_openFile(struct AppDel *self, SEL _cmd, id sender, id filename)
id t_alertbox = ALLOC_INIT_OBJC_CLASS("NSAlert");
objc_msgSend(t_alertbox, sel_getUid("setMessageText:"), filename);
objc_msgSend(t_alertbox, sel_getUid("runModal"));
return YES;
BOOL AppDel_openFiles(struct AppDel *self, SEL _cmd, id sender, id filenames)
// Pick first filename in the array
id first_nsstr = objc_msgSend(filenames, sel_getUid("firstObject"));
// Do a little dance here to get the C string, just to see that it's possible.
const char* c_str = (const char*)objc_msgSend(first_nsstr, sel_getUid("UTF8String"));
id msg_text = objc_msgSend((id)objc_getClass("NSString"), sel_getUid("alloc"));
msg_text = objc_msgSend(msg_text, sel_getUid("initWithUTF8String:"), c_str);
id t_alertbox = ALLOC_INIT_OBJC_CLASS("NSAlert");
objc_msgSend(t_alertbox, sel_getUid("setMessageText:"), msg_text);
objc_msgSend(t_alertbox, sel_getUid("runModal"));
return YES;
// Set up the delegate class that has the two openFile and openFiles methods.
static void init_delegate_class()
AppDelClass = objc_allocateClassPair((Class) objc_getClass("NSObject"), "AppDelegate", 0);
class_addMethod(AppDelClass, sel_getUid("application:openFile:"), (IMP) AppDel_openFile, "i@:@:@");
class_addMethod(AppDelClass, sel_getUid("application:openFiles:"), (IMP) AppDel_openFiles, "i@:@:@");
void init_app(void)
objc_msgSend((id)objc_getClass("NSApplication"), sel_getUid("sharedApplication"));
if (NSApp == NULL)
fprintf(stderr,"Failed to initialized NSApplication... terminating...\n");
id appDelObj = ALLOC_INIT_OBJC_CLASS("AppDelegate");
objc_msgSend(NSApp, sel_getUid("setDelegate:"), appDelObj);
objc_msgSend(NSApp, sel_getUid("run"));
int main(int argc, char** argv)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment