Skip to content
This repository was archived by the owner on May 9, 2023. It is now read-only.

Commit 95e8b3a

Browse files
committed
fix string unbox
1 parent b681453 commit 95e8b3a

File tree

2 files changed

+65
-59
lines changed

2 files changed

+65
-59
lines changed

src/Core/Runtime/Il2Cpp/Il2CppReflection.cs

Lines changed: 63 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,31 @@ public override T TryCast<T>(object obj)
4444
}
4545
}
4646

47+
public override void BoxStringToType(ref object value, Type castTo)
48+
{
49+
if (castTo == typeof(Il2CppSystem.String))
50+
value = (Il2CppSystem.String)(value as string);
51+
else
52+
value = (Il2CppSystem.Object)(value as string);
53+
}
54+
55+
public override string UnboxString(object value)
56+
{
57+
if (value is string s)
58+
return s;
59+
60+
s = null;
61+
// strings boxed as Il2CppSystem.Objects can behave weirdly.
62+
// GetActualType will find they are a string, but if its boxed
63+
// then we need to unbox it like this...
64+
if (value is Il2CppSystem.Object cppObject)
65+
s = cppObject.ToString();
66+
else if (value is Il2CppSystem.String cppString)
67+
s = cppString;
68+
69+
return s;
70+
}
71+
4772
public override string ProcessTypeNameInString(Type type, string theString, ref string typeName)
4873
{
4974
if (!Il2CppTypeNotNull(type))
@@ -334,64 +359,6 @@ internal static bool LoadModuleInternal(string fullPath)
334359
return false;
335360
}
336361

337-
public override void BoxStringToType(ref object value, Type castTo)
338-
{
339-
if (castTo == typeof(Il2CppSystem.String))
340-
value = (Il2CppSystem.String)(value as string);
341-
else
342-
value = (Il2CppSystem.Object)(value as string);
343-
}
344-
345-
// ~~~~~~~~~~ not used ~~~~~~~~~~~~
346-
347-
// cached il2cpp unbox methods
348-
internal static readonly Dictionary<string, MethodInfo> s_unboxMethods = new Dictionary<string, MethodInfo>();
349-
350-
/// <summary>
351-
/// Attempt to unbox the object to the underlying struct type.
352-
/// </summary>
353-
/// <param name="obj">The object which is a struct underneath.</param>
354-
/// <returns>The struct if successful, otherwise null.</returns>
355-
public static object Unbox(object obj) => Unbox(obj, Instance.GetActualType(obj));
356-
357-
/// <summary>
358-
/// Attempt to unbox the object to the struct type.
359-
/// </summary>
360-
/// <param name="obj">The object which is a struct underneath.</param>
361-
/// <param name="type">The type of the struct you want to unbox to.</param>
362-
/// <returns>The struct if successful, otherwise null.</returns>
363-
public static object Unbox(object obj, Type type)
364-
{
365-
if (!type.IsValueType)
366-
return null;
367-
368-
if (!(obj is Il2CppSystem.Object))
369-
return obj;
370-
371-
var name = type.AssemblyQualifiedName;
372-
373-
if (!s_unboxMethods.ContainsKey(name))
374-
{
375-
s_unboxMethods.Add(name, typeof(Il2CppObjectBase)
376-
.GetMethod("Unbox")
377-
.MakeGenericMethod(type));
378-
}
379-
380-
return s_unboxMethods[name].Invoke(obj, new object[0]);
381-
}
382-
383-
public override string UnboxString(object value)
384-
{
385-
string s = null;
386-
// strings boxed as Il2CppSystem.Objects can behave weirdly.
387-
// GetActualType will find they are a string, but if its boxed
388-
// then we need to unbox it like this...
389-
if (!(value is string) && value is Il2CppSystem.Object cppobj)
390-
s = cppobj.ToString();
391-
392-
return s;
393-
}
394-
395362
internal static readonly Dictionary<Type, MethodInfo> s_getEnumeratorMethods = new Dictionary<Type, MethodInfo>();
396363

397364
internal static readonly Dictionary<Type, EnumeratorInfo> s_enumeratorInfos = new Dictionary<Type, EnumeratorInfo>();
@@ -497,6 +464,44 @@ private void EnumerateCppHashtable(Il2CppSystem.Collections.Hashtable hashtable,
497464
values.Add(bucket.val);
498465
}
499466
}
467+
468+
// ~~~~~~~~~~ not used ~~~~~~~~~~~~
469+
470+
// cached il2cpp unbox methods
471+
internal static readonly Dictionary<string, MethodInfo> s_unboxMethods = new Dictionary<string, MethodInfo>();
472+
473+
/// <summary>
474+
/// Attempt to unbox the object to the underlying struct type.
475+
/// </summary>
476+
/// <param name="obj">The object which is a struct underneath.</param>
477+
/// <returns>The struct if successful, otherwise null.</returns>
478+
public static object Unbox(object obj) => Unbox(obj, Instance.GetActualType(obj));
479+
480+
/// <summary>
481+
/// Attempt to unbox the object to the struct type.
482+
/// </summary>
483+
/// <param name="obj">The object which is a struct underneath.</param>
484+
/// <param name="type">The type of the struct you want to unbox to.</param>
485+
/// <returns>The struct if successful, otherwise null.</returns>
486+
public static object Unbox(object obj, Type type)
487+
{
488+
if (!type.IsValueType)
489+
return null;
490+
491+
if (!(obj is Il2CppSystem.Object))
492+
return obj;
493+
494+
var name = type.AssemblyQualifiedName;
495+
496+
if (!s_unboxMethods.ContainsKey(name))
497+
{
498+
s_unboxMethods.Add(name, typeof(Il2CppObjectBase)
499+
.GetMethod("Unbox")
500+
.MakeGenericMethod(type));
501+
}
502+
503+
return s_unboxMethods[name].Invoke(obj, new object[0]);
504+
}
500505
}
501506
}
502507

src/UI/InteractiveValues/InteractiveString.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ public InteractiveString(object value, Type valueType) : base(value, valueType)
2424

2525
public override void OnValueUpdated()
2626
{
27-
Value = RuntimeProvider.Instance.Reflection.UnboxString(Value);
27+
if (!(Value is string) && Value != null)
28+
Value = RuntimeProvider.Instance.Reflection.UnboxString(Value);
2829

2930
base.OnValueUpdated();
3031
}

0 commit comments

Comments
 (0)