Skip to content

Instantly share code, notes, and snippets.

@yohhoy
Created June 14, 2019 18:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yohhoy/78b5f8fb425fc1aa14090af96164eb65 to your computer and use it in GitHub Desktop.
Save yohhoy/78b5f8fb425fc1aa14090af96164eb65 to your computer and use it in GitHub Desktop.
invoke Obj-C from pure-C
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <objc/message.h>
SEL sel_propSetter(Class clazz, const char* pname)
{
char* attr = property_copyAttributeValue(class_getProperty(clazz, pname), "S");
if (!attr) {
attr = malloc(strlen(pname) + sizeof("set") + 1/*:*/);
sprintf(attr, "set%c%s:", toupper(*pname), pname + 1);
}
SEL uid = sel_getUid(attr ? attr : pname);
free(attr);
return uid;
}
SEL sel_propGetter(Class clazz, const char* pname)
{
char* attr = property_copyAttributeValue(class_getProperty(clazz, pname), "G");
SEL uid = sel_getUid(attr ? attr : pname);
free(attr);
return uid;
}
void invokeObjC(void)
{
Class clsTestClass = objc_getClass("TestClass");
id obj = objc_msgSend(objc_msgSend((id)clsTestClass, sel_registerName("alloc")), sel_registerName("init"));
printf("intValue=%d\n", (int)objc_msgSend(obj, sel_propGetter(clsTestClass, "intValue")));
printf("boolValue=%d\n", (BOOL)objc_msgSend(obj, sel_propGetter(clsTestClass, "boolValue")));
objc_msgSend(obj, sel_propSetter(clsTestClass, "intValue"), 100);
objc_msgSend(obj, sel_propSetter(clsTestClass, "boolValue"), 0);
objc_msgSend(obj, sel_registerName("method"));
objc_msgSend(obj, sel_registerName("dealloc"));
}
#import <Foundation/Foundation.h>
@interface TestClass : NSObject
- (void)method;
@property(nonatomic) int intValue;
@property(nonatomic) BOOL boolValue;
@end
@implementation TestClass
- (instancetype)init {
NSLog(@"TestClass init");
if (self = [super init]) {
_intValue = 42;
_boolValue = YES;
}
return self;
}
- (void)dealloc {
NSLog(@"TestClass dealloc");
}
- (void)method {
NSLog(@"TestClass method i=%d b=%d", _intValue, _boolValue);
}
@end
#pragma mark -
void runObjC() {
TestClass *obj = [[TestClass alloc] init];
NSLog(@"intValue=%d", obj.intValue);
NSLog(@"boolValue=%d", obj.boolValue);
obj.intValue = 100;
obj.boolValue = 0;
[obj method];
}
extern void invokeObjC(void);
int main(int argc, const char * argv[]) {
@autoreleasepool { runObjC(); }
invokeObjC();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment