figure out how to use objective-c reflection
hansent opened this issue · 8 comments
Class uiview_cls = objc_getClass("UIWindow");
unsigned int num_methods = 0;
Method* class_methods = class_copyMethodList(uiview_cls, &num_methods);
NSLog(@"methods for UIWindow:");
for(int i=0; i<num_methods; i++){
const char* method_name = sel_getName(method_getName(class_methods[i]));
const char* method_args = method_getTypeEncoding(class_methods[i]);
NSString *name = [NSString stringWithUTF8String:method_name];
NSString *args = [NSString stringWithUTF8String:method_args];
NSLog(@"name: '%@', type_enc: %@\n", name, args);
}
produces:
https://gist.github.com/3353346
see focumetation for obj-c runtime here: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html
nice start :)
using NSBundle, we can load frameworks at runtime (not sure if possible on iOS), but otherwise, all frameworks have to be linked at compile time:
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/LoadingCode/Tasks/LoadingBundles.html#//apple_ref/doc/uid/20001273-CJBDDCAB
C code (needs to link against libobjc.dylib [and if getting e.g. NSWindow class, also AppKit.framework]):
#include <stdio.h>
#include "objc/runtime.h"
int main(int argc, const char * argv[])
{
Class _NSWindow = (Class)objc_getClass("NSWindow");
printf("getting class NSWindow");
unsigned int num_methods = 0;
Method* class_methods = class_copyMethodList(_NSWindow, &num_methods);
for(int i=0; i<num_methods; i++){
const char* name = sel_getName(method_getName(class_methods[i]));
const char* typeenc = method_getTypeEncoding(class_methods[i]);
printf("name: '%s', type_enc: %s\n", name, typeenc);
}
return 0;
}
objc/runtime.h:
https://gist.github.com/3362098
mhhh...C code in xcode runs OK, but trying to do it from cython the class registry seems to be empty:
http://www.stypi.com/hansent/simple.pyx compiles ok. since it's using objc_getRequiredClass it also errors, but problem is registry is not created with classes...not sure how to do it/what to load, tried copying all compiler args/linker args from Xcode c example...but still the same
dlopen() the foundation make the example works. fix commited
done!