static unsafe void InitializeCoreCLRBridge(InitializationOptions *options) { if (options->xamarin_objc_msgsend != IntPtr.Zero) { ObjectiveCMarshal.SetMessageSendCallback(ObjectiveCMarshal.MessageSendFunction.MsgSend, options->xamarin_objc_msgsend); } if (options->xamarin_objc_msgsend_super != IntPtr.Zero) { ObjectiveCMarshal.SetMessageSendCallback(ObjectiveCMarshal.MessageSendFunction.MsgSendSuper, options->xamarin_objc_msgsend_super); } if (options->xamarin_objc_msgsend_stret != IntPtr.Zero) { ObjectiveCMarshal.SetMessageSendCallback(ObjectiveCMarshal.MessageSendFunction.MsgSendStret, options->xamarin_objc_msgsend_stret); } if (options->xamarin_objc_msgsend_super_stret != IntPtr.Zero) { ObjectiveCMarshal.SetMessageSendCallback(ObjectiveCMarshal.MessageSendFunction.MsgSendSuperStret, options->xamarin_objc_msgsend_super_stret); } delegate * unmanaged <void> beginEndCallback = (delegate * unmanaged <void>)options->reference_tracking_begin_end_callback; delegate * unmanaged <IntPtr, int> isReferencedCallback = (delegate * unmanaged <IntPtr, int>)options->reference_tracking_is_referenced_callback; delegate * unmanaged <IntPtr, void> trackedObjectEnteredFinalization = (delegate * unmanaged <IntPtr, void>)options->reference_tracking_tracked_object_entered_finalization; ObjectiveCMarshal.Initialize(beginEndCallback, isReferencedCallback, trackedObjectEnteredFinalization, UnhandledExceptionPropagationHandler); }
static unsafe void SetPendingException(MonoObject *exception_obj) { var exc = (Exception)GetMonoObjectTarget(exception_obj); log_coreclr($"Runtime.SetPendingException ({exc})"); ObjectiveCMarshal.SetMessageSendPendingException(exc); }
private static void ValidateSetMessageSendPendingExceptionImpl(MessageSendFunction msgSend) { if (!LibObjC.SupportedOnPlatform(msgSend)) { return; } IntPtr func = msgSend switch { MessageSendFunction.MsgSend => (IntPtr)(delegate * unmanaged <IntPtr, IntPtr, IntPtr>) & MsgSend, MessageSendFunction.MsgSendFpret => (IntPtr)(delegate * unmanaged <IntPtr, IntPtr, IntPtr>) & MsgSendFpret, MessageSendFunction.MsgSendStret => (IntPtr)(delegate * unmanaged <IntPtr *, IntPtr, IntPtr, void>) & MsgSendStret, MessageSendFunction.MsgSendSuper => (IntPtr)(delegate * unmanaged <IntPtr, IntPtr, IntPtr>) & MsgSendSuper, MessageSendFunction.MsgSendSuperStret => (IntPtr)(delegate * unmanaged <IntPtr *, IntPtr, IntPtr, void>) & MsgSendSuperStret, _ => throw new Exception($"Unknown {nameof(MessageSendFunction)}"), }; // Override message send function // // We are using the overriding mechanism to enable validating in the Libraries test suite. // Technically any Objective-C code that is entered via msgSend could call the managed SetMessageSendPendingException() // and it would be thrown when returning from the P/Invoke. This approach avoids us having to // create a pure Objective-C library for testing this behavior. ObjectiveCMarshal.SetMessageSendCallback(msgSend, func); // Call message send function through P/Invoke IntPtr inst = IntPtr.Zero; IntPtr sel = IntPtr.Zero; Exception ex = Assert.Throws <PendingException>(() => LibObjC.CallPInvoke(msgSend, inst, sel)); Assert.Equal(msgSend.ToString(), ex.Message); }
static void Validate_ReferenceTrackingAPIs_InvalidArgs() { Console.WriteLine($"Running {nameof(Validate_ReferenceTrackingAPIs_InvalidArgs)}..."); delegate * unmanaged <void> beginEndCallback; delegate * unmanaged <IntPtr, int> isReferencedCallback; delegate * unmanaged <IntPtr, void> trackedObjectEnteredFinalization; NativeObjCMarshalTests.GetExports(out beginEndCallback, out isReferencedCallback, out trackedObjectEnteredFinalization); Assert.Throws <ArgumentNullException>( () => { ObjectiveCMarshal.Initialize(null, isReferencedCallback, trackedObjectEnteredFinalization, OnUnhandledExceptionPropagationHandler); }); Assert.Throws <ArgumentNullException>( () => { ObjectiveCMarshal.Initialize(beginEndCallback, null, trackedObjectEnteredFinalization, OnUnhandledExceptionPropagationHandler); }); Assert.Throws <ArgumentNullException>( () => { ObjectiveCMarshal.Initialize(beginEndCallback, isReferencedCallback, null, OnUnhandledExceptionPropagationHandler); }); Assert.Throws <ArgumentNullException>( () => { ObjectiveCMarshal.Initialize(beginEndCallback, isReferencedCallback, trackedObjectEnteredFinalization, null); }); Assert.Throws <ArgumentNullException>( () => { ObjectiveCMarshal.CreateReferenceTrackingHandle(null, out _); }); }
// See "Toggle-ref support for CoreCLR" in coreclr-bridge.m for more information. internal static void RegisterToggleReferenceCoreCLR(NSObject obj, IntPtr handle, bool isCustomType) { var gchandle = ObjectiveCMarshal.CreateReferenceTrackingHandle(obj, out var info); unsafe { TrackedObjectInfo *tracked_info; fixed(void *ptr = info) tracked_info = (TrackedObjectInfo *)ptr; tracked_info->Handle = handle; tracked_info->Flags = obj.FlagsInternal; obj.tracked_object_info = tracked_info; obj.tracked_object_handle = gchandle; log_coreclr($"RegisterToggleReferenceCoreCLR ({obj.GetType ().FullName}, 0x{handle.ToString ("x")}, {isCustomType}) => Info=0x{((IntPtr) tracked_info).ToString ("x")} Flags={tracked_info->Flags}"); } // Make sure the GCHandle we have is a weak one for custom types. if (isCustomType) { xamarin_switch_gchandle(handle, true); } }
private static IntPtr SetPendingException([CallerMemberName] string callerName = "") { ObjectiveCMarshal.SetMessageSendPendingException(new PendingException(callerName)); return(IntPtr.Zero); }