kivy/pyobjus

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

tito commented

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;
}

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

tito commented

dlopen() the foundation make the example works. fix commited

tito commented

done!