How to use NSSetUncaughtExceptionHandler of iOS in Elements?


(James Esword) #1

The signature of Foundation.NSSetUncaughtExceptionHandler:

public void NSSetUncaughtExceptionHandler(Void* param0)

requires a c-style function pointer parameter “Void*”.

Could someone explain how to declare a method which can be converted to “Void*” in Elements?


(James Esword) #2

Just find a very tricky way to “extract” the function address, and the function seems be invoked successfully. But it’s still failed to run properly, because the access to NSException parameter will cause error.

Any idea?

Here’s my test example:
IOSApp1.zip (108.0 KB)

public static class FuncHelper {

    struct FuncBlock {
        public void *isa;
        public int flags;
        public int reserved;
        public NativeUInt address;
        public void* dp;
    }

    public static Void* getPointer(object func) {
        return (Void*)((FuncBlock*)(*((NativeUInt*)(&func))))->address;
    }
}

public delegate void ExceptionHandlerFunc(NSException ex);

// Try to declare a global function instead of a member function
public static void onUncaughtException(NSException exception) {
    var reason = exception.reason;  // EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    Foundation.NSLog(reason);
}

[UIApplicationMain, IBObject]
class AppDelegate : IUIApplicationDelegate {

    public BOOL application(UIApplication application) didFinishLaunchingWithOptions(NSDictionary launchOptions) {

        var window = new UIWindow(UIScreen.mainScreen().bounds);
        window.rootViewController = new UIViewController withNibName(null) bundle(null);
        window.makeKeyAndVisible();

        // setup & throw
        ExceptionHandlerFunc func = onUncaughtException;
        NSSetUncaughtExceptionHandler(FuncHelper.getPointer(func));
        throw NSException.exceptionWithName("") reason("TEST ONLY") userInfo(null);

        return true;
    }
}

(James Esword) #3

@ck Hi Carlo, I’m still wondering what’s the official way to call Cocoa APIs which require a c-style function pointer as parameter in Elements.


(Carlo Kok) #4

Isn’t NSSetUncaughtExceptionHandler defined as:
void NSSetUncaughtExceptionHandler(NSUncaughtExceptionHandler *);

? If so you can use that type (NSUncaughtExceptionHandler). Elements on Cocoa has two different kinds of delegates: “Blocks” and “Function Pointers”. Currently delegates map to blocks (blocks have a “this” pointer, function pointers don’t). We don’t yet have a syntax for function pointers in C#. However to satisfy above method signature you need to define a static method outside a class (just move it before or after your class). Then you can use it as the parameter for this call.


(RemObjects) #5

Thanks, logged as bugs://75560


(marc hoffman) #6

Yes we do? [FunctionPointer] attribute. https://docs.elementscompiler.com/Concepts/Aspects/SpecialAttributesCocoa/


(James Esword) #7

Oh yes the static method outside a class can be passed as parameter directly and it works fine. Thanks!

Currently it seems there’s no such a type NSUncaughtExceptionHandler in Elements, and the definition of NSSetUncaughtExceptionHandler is:

But I understand if there’s no syntax for function pointer (sth like typedef in C), there’s no better way to define this method.


(James Esword) #8

Awesome! [FunctionPointer] works as expected.


(RemObjects) #9

bugs://75560 got closed with status nochangereq.