[UIKit] Wrap the call to UIApplicationMain in a @try/@catch handler. (#15746)

Wrap the call to UIApplicationMain in a @try/@catch handler, and convert any
Objective-C exceptions to a managed exception.

This way the managed Main method (which calls UIApplication.Main) will be able
to catch any Objective-C exceptions.
This commit is contained in:
Rolf Bjarne Kvinge 2022-08-26 13:56:33 +02:00 коммит произвёл GitHub
Родитель a7690ee03b
Коммит 68de101ce6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 36 добавлений и 2 удалений

Просмотреть файл

@ -13,6 +13,11 @@
extern "C" {
#endif
// The inclusion of "_Nullable" in the signature for xamarin_UIApplicationMain makes clang complain about missing nullability info for other methods in this file.
// We don't want to fix that right now (but feel free to do so if you're reading this), so ignore the missing nullability info warning for the methods in question.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnullability-completeness"
void * xamarin_IntPtr_objc_msgSend_IntPtr (id self, SEL sel, void *a);
void * xamarin_IntPtr_objc_msgSendSuper_IntPtr (struct objc_super *super, SEL sel, void *a);
@ -56,6 +61,10 @@ void * xamarin_IntPtr_objc_msgSendSuper_IntPtr_UInt32_nint_UInt32 (struct objc_s
void * xamarin_IntPtr_objc_msgSend_IntPtr_UInt64_nint_UInt64 (id self, SEL sel, void *a, uint64_t b, xm_nint_t c, uint64_t d);
void * xamarin_IntPtr_objc_msgSendSuper_IntPtr_UInt64_nint_UInt64 (struct objc_super *super, SEL sel, void *a, uint64_t b, xm_nint_t c, uint64_t d);
#pragma clang diagnostic push
int xamarin_UIApplicationMain (int argc, char * _Nullable argv[_Nonnull], NSString * _Nullable principalClassName, NSString * _Nullable delegateClassName, GCHandle *exception_gchandle);
/* Types copied from headers */
/* We need to do this for now, since we must be able to build XM on older OSXs */

Просмотреть файл

@ -13,6 +13,10 @@
#include "bindings.h"
#include <dlfcn.h>
#if !TARGET_OS_OSX && !TARGET_OS_WATCH
#include <UIKit/UIKit.h>
#endif
/*
* Hand-written bindings to support ObjectiveC exceptions.
* Reference:
@ -112,3 +116,17 @@ xamarin_CGPoint__VNImagePointForFaceLandmarkPoint_Vector2_CGRect_nuint_nuint_str
return func (flp, faceBoundingBox, imageWidth, imageHeight);
}
/* UIKit bindings */
#if !TARGET_OS_OSX && !TARGET_OS_WATCH
int xamarin_UIApplicationMain (int argc, char * _Nullable argv[_Nonnull], NSString * _Nullable principalClassName, NSString * _Nullable delegateClassName, GCHandle *exception_gchandle)
{
@try {
*exception_gchandle = INVALID_GCHANDLE;
return UIApplicationMain (argc, argv, principalClassName, delegateClassName);
} @catch (NSException *e) {
xamarin_process_nsexception_using_mode (e, false, exception_gchandle);
return 1;
}
}
#endif // !TARGET_OS_OSX

Просмотреть файл

@ -49,8 +49,15 @@ namespace UIKit {
#if !WATCH
// We link with __Internal here so that this function is interposable from third-party native libraries.
// See: https://github.com/xamarin/MicrosoftInTune/issues/3 for an example.
[DllImport (/*Constants.UIKitLibrary*/ "__Internal")]
extern static int UIApplicationMain (int argc, /* char[]* */ string []? argv, /* NSString* */ IntPtr principalClassName, /* NSString* */ IntPtr delegateClassName);
[DllImport ("__Internal")]
extern static int xamarin_UIApplicationMain (int argc, /* char[]* */ string []? argv, /* NSString* */ IntPtr principalClassName, /* NSString* */ IntPtr delegateClassName, out IntPtr gchandle);
static int UIApplicationMain (int argc, /* char[]* */ string []? argv, /* NSString* */ IntPtr principalClassName, /* NSString* */ IntPtr delegateClassName)
{
var rv = xamarin_UIApplicationMain (argc, argv, principalClassName, delegateClassName, out var gchandle);
Runtime.ThrowException (gchandle);
return rv;
}
#endif
// called from NSExtension.Initialize (so other, future stuff, can be added if needed)