Convert Runtime.ConvertNSStringToSmartEnum and Runtime.ConvertSmartEnumToNSString to use GCHandle.
These methods were already partially using GCHandles, so convert the parameter using ObjectWrapper to GCHandle, and port the rest of the existing logic to use the new helper API.
This commit is contained in:
Родитель
b360263f2c
Коммит
b0974e8317
|
@ -264,15 +264,15 @@
|
|||
},
|
||||
|
||||
new XDelegate ("NSString *", "IntPtr", "xamarin_convert_smart_enum_to_nsstring",
|
||||
"void *", "IntPtr", "value"
|
||||
"GCHandle->MonoObject *", "IntPtr", "value"
|
||||
) {
|
||||
WrappedManagedFunction = "ConvertSmartEnumToNSString",
|
||||
OnlyDynamicUsage = true,
|
||||
},
|
||||
|
||||
new XDelegate ("void *", "IntPtr", "xamarin_convert_nsstring_to_smart_enum",
|
||||
new XDelegate ("GCHandle->MonoObject *", "IntPtr", "xamarin_convert_nsstring_to_smart_enum",
|
||||
"NSString *", "IntPtr", "value",
|
||||
"MonoReflectionType *", "IntPtr", "type"
|
||||
"GCHandle->MonoReflectionType *", "IntPtr", "type"
|
||||
) {
|
||||
WrappedManagedFunction = "ConvertNSStringToSmartEnum",
|
||||
OnlyDynamicUsage = true,
|
||||
|
|
|
@ -1400,9 +1400,7 @@ xamarin_smart_enum_to_nsstring (MonoObject *value, void *context /* token ref */
|
|||
guint32 context_ref = GPOINTER_TO_UINT (context);
|
||||
if (context_ref == INVALID_TOKEN_REF) {
|
||||
// This requires the dynamic registrar to invoke the correct conversion function
|
||||
uint32_t handle = mono_gchandle_new (value, FALSE);
|
||||
NSString *rv = xamarin_convert_smart_enum_to_nsstring (GINT_TO_POINTER (handle), exception_gchandle);
|
||||
mono_gchandle_free (handle);
|
||||
NSString *rv = xamarin_convert_smart_enum_to_nsstring (value, exception_gchandle);
|
||||
return rv;
|
||||
} else {
|
||||
// The static registrar found the correct conversion function, and provided a token ref we can use
|
||||
|
@ -1435,16 +1433,13 @@ void *
|
|||
xamarin_nsstring_to_smart_enum (id value, void *ptr, MonoClass *managedType, void *context, guint32 *exception_gchandle)
|
||||
{
|
||||
guint32 context_ref = GPOINTER_TO_UINT (context);
|
||||
uint32_t gc_handle = 0;
|
||||
MonoObject *obj;
|
||||
|
||||
if (context_ref == INVALID_TOKEN_REF) {
|
||||
// This requires the dynamic registrar to invoke the correct conversion function
|
||||
void *rv = xamarin_convert_nsstring_to_smart_enum (value, mono_type_get_object (mono_domain_get (), mono_class_get_type (managedType)), exception_gchandle);
|
||||
obj = xamarin_convert_nsstring_to_smart_enum (value, mono_type_get_object (mono_domain_get (), mono_class_get_type (managedType)), exception_gchandle);
|
||||
if (*exception_gchandle != 0)
|
||||
return ptr;
|
||||
gc_handle = GPOINTER_TO_UINT (rv);
|
||||
obj = mono_gchandle_get_target (gc_handle);
|
||||
} else {
|
||||
// The static registrar found the correct conversion function, and provided a token ref we can use
|
||||
// to find it (and invoke it), without needing the dynamic registrar.
|
||||
|
@ -1471,8 +1466,6 @@ xamarin_nsstring_to_smart_enum (id value, void *ptr, MonoClass *managedType, voi
|
|||
ptr = xamarin_calloc (size);
|
||||
void *value_ptr = mono_object_unbox (obj);
|
||||
memcpy (ptr, value_ptr, size);
|
||||
if (context_ref == INVALID_TOKEN_REF)
|
||||
mono_gchandle_free (gc_handle);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -363,7 +363,7 @@ namespace ObjCRuntime {
|
|||
// returns: a handle to a native NSString *
|
||||
static IntPtr ConvertSmartEnumToNSString (IntPtr value_handle)
|
||||
{
|
||||
var value = GCHandle.FromIntPtr (value_handle).Target;
|
||||
var value = GetGCHandleTarget (value_handle);
|
||||
var smart_type = value.GetType ();
|
||||
MethodBase getConstantMethod, getValueMethod;
|
||||
if (!Registrar.IsSmartEnum (smart_type, out getConstantMethod, out getValueMethod))
|
||||
|
@ -380,13 +380,13 @@ namespace ObjCRuntime {
|
|||
// returns: GCHandle to a (smart) enum value. Caller must free the GCHandle.
|
||||
static IntPtr ConvertNSStringToSmartEnum (IntPtr value, IntPtr type)
|
||||
{
|
||||
var smart_type = (Type) ObjectWrapper.Convert (type);
|
||||
var smart_type = (Type) GetGCHandleTarget (type);
|
||||
var str = GetNSObject<NSString> (value);
|
||||
MethodBase getConstantMethod, getValueMethod;
|
||||
if (!Registrar.IsSmartEnum (smart_type, out getConstantMethod, out getValueMethod))
|
||||
throw ErrorHelper.CreateError (8024, $"Could not find a valid extension type for the smart enum '{smart_type.FullName}'. Please file a bug at https://github.com/xamarin/xamarin-macios/issues/new.");
|
||||
var rv = ((MethodInfo) getValueMethod).Invoke (null, new object [] { str });
|
||||
return GCHandle.ToIntPtr (GCHandle.Alloc (rv));
|
||||
return AllocGCHandle (rv);
|
||||
}
|
||||
|
||||
#region Wrappers for delegate callbacks
|
||||
|
|
Загрузка…
Ссылка в новой задаче