public void OffsetOfTest() { var obj = new Tester(); var int64_offset = TypeHelper.OffsetOf(typeof(Tester).GetField(nameof(Tester.public_int64))); var string_offset = TypeHelper.OffsetOf(typeof(Tester).GetField(nameof(Tester.public_string))); var static_int_offset = TypeHelper.OffsetOf(typeof(Tester).GetField(nameof(Tester.static_int))); var static_string_offset = TypeHelper.OffsetOf(typeof(Tester).GetField(nameof(Tester.static_string))); var static_object_offset = TypeHelper.OffsetOf(typeof(Tester).GetField(nameof(Tester.static_object))); var struct_int64_offset = TypeHelper.OffsetOf(typeof(Tester_Struct).GetField(nameof(Tester_Struct.public_int64))); var struct_string_offset = TypeHelper.OffsetOf(typeof(Tester_Struct).GetField(nameof(Tester_Struct.public_string))); var struct_static_bool_offset = TypeHelper.OffsetOf(typeof(Tester_Struct).GetField(nameof(Tester_Struct.static_bool))); var struct_static_byte_offset = TypeHelper.OffsetOf(typeof(Tester_Struct).GetField(nameof(Tester_Struct.static_byte))); var gc_statics_base_pointer = (void *)TypeHelper.GetGCStaticsBasePointer(typeof(Tester)); var non_gc_statics_base_pointer = (void *)TypeHelper.GetNonGCStaticsBasePointer(typeof(Tester)); var struct_non_gc_statics_base_pointer = (void *)TypeHelper.GetNonGCStaticsBasePointer(typeof(Tester_Struct)); Underlying.AddByteOffset(ref TypeHelper.Unbox <long>(obj), int64_offset) = 999; Underlying.AddByteOffset(ref TypeHelper.Unbox <string>(obj), string_offset) = "F**k"; AreEqual(obj.public_int64, 999); AreEqual(obj.public_string, "F**k"); Underlying.AddByteOffset(ref Underlying.AsRef <int>(non_gc_statics_base_pointer), static_int_offset) = 123; Underlying.AddByteOffset(ref Underlying.AsRef <string>(gc_statics_base_pointer), static_string_offset) = "Dogwei"; Underlying.AddByteOffset(ref Underlying.AsRef <object>(gc_statics_base_pointer), static_object_offset) = obj; AreEqual(Tester.static_int, 123); AreEqual(Tester.static_string, "Dogwei"); AreEqual(Tester.static_object, obj); var value = new Tester_Struct(); Underlying.AddByteOffset(ref Underlying.As <Tester_Struct, long>(ref value), struct_int64_offset) = 999; Underlying.AddByteOffset(ref Underlying.As <Tester_Struct, string>(ref value), struct_string_offset) = "F**k"; AreEqual(value.public_int64, 999); AreEqual(value.public_string, "F**k"); Underlying.AddByteOffset(ref Underlying.AsRef <bool>(struct_non_gc_statics_base_pointer), struct_static_bool_offset) = true; Underlying.AddByteOffset(ref Underlying.AsRef <byte>(struct_non_gc_statics_base_pointer), struct_static_byte_offset) = 128; AreEqual(Tester_Struct.static_bool, true); AreEqual(Tester_Struct.static_byte, 128); }
private protected override void InitializeByValue(PropertyInfo propertyInfo, XBindingFlags flags) { base.InitializeByValue(propertyInfo, flags); if ((flags & XBindingFlags.RWAutoPropertyDirectRW) != 0 && TypeHelper.IsAutoProperty(propertyInfo, out var fieldInfo) && fieldInfo != null) { try { var offset = TypeHelper.OffsetOf(fieldInfo); _get = (obj) => Underlying.AddByteOffset(ref TypeHelper.Unbox <TValue>(obj), offset); _set = (obj, value) => Underlying.AddByteOffset(ref TypeHelper.Unbox <TValue>(obj), offset) = value; return; } catch { } } if (_get is null) { var getMethod = propertyInfo.GetGetMethod((flags & XBindingFlags.NonPublic) != 0); if (getMethod != null) { _get = MethodHelper.CreateDelegate <XClassGetValueHandler <TClass, TValue> >(getMethod, false); } } if (_set is null) { var setMethod = propertyInfo.GetSetMethod((flags & XBindingFlags.NonPublic) != 0); if (setMethod != null) { _set = MethodHelper.CreateDelegate <XClassSetValueHandler <TClass, TValue> >(setMethod, false); } } }
private protected override void InitializeByValue(PropertyInfo propertyInfo, XBindingFlags flags) { base.InitializeByValue(propertyInfo, flags); if ((flags & XBindingFlags.RWAutoPropertyDirectRW) != 0 /* || !VersionDifferences.IsSupportEmit */) { if (TypeHelper.IsAutoProperty(propertyInfo, out var fieldInfo) && fieldInfo != null) { try { var offset = TypeHelper.OffsetOf(fieldInfo); _get = (obj) => Underlying.AddByteOffset(ref TypeHelper.Unbox <TValue>(obj), offset); _set = (obj, value) => Underlying.AddByteOffset(ref TypeHelper.Unbox <TValue>(obj), offset) = value; return; } catch { } } } if (_get is null) { var getMethod = propertyInfo.GetGetMethod((flags & XBindingFlags.NonPublic) != 0); if (getMethod != null) { var __get = (GetValueHandler)Delegate.CreateDelegate(typeof(GetValueHandler), getMethod); _get = VersionDifferences.IsSupportEmit ? __get : AOTCheck; TValue AOTCheck(TClass obj) { try { return(__get(obj)); } catch (ExecutionEngineException) { __get = AOT; return(AOT(obj)); } finally { _get = __get; } } TValue AOT(TClass obj) { return((TValue)getMethod.Invoke(obj, null)); } } } if (_set is null) { var setMethod = propertyInfo.GetSetMethod((flags & XBindingFlags.NonPublic) != 0); if (setMethod != null) { var __set = (SetValueHandler)Delegate.CreateDelegate(typeof(SetValueHandler), setMethod); _set = VersionDifferences.IsSupportEmit ? __set : AOTCheck; void AOTCheck(TClass obj, TValue value) { try { __set(obj, value); } catch (ExecutionEngineException) { __set = AOT; AOT(obj, value); } finally { _set = __set; } } void AOT(TClass obj, TValue value) { setMethod.Invoke(obj, new object[] { value }); } } } }
public ref TValue GetReference(object obj) => ref Underlying.AddByteOffset(ref TypeHelper.Unbox <TValue>(obj), offset);
/// <summary> /// 获取字段的值的引用。 /// </summary> /// <param name="obj">对象的引用</param> /// <returns>返回字段的值的引用</returns> public ref TValue GetReference(ref TStruct obj) => ref Underlying.AddByteOffset(ref Underlying.As <TStruct, TValue>(ref obj), offset);
public static void StoreStructField <TValue>(ref TValue obj, TValue value, int offset) { Underlying.AddByteOffset(ref obj, offset) = value; }
public static TValue LoadStructField <TValue>(ref TValue obj, int offset) { return(Underlying.AddByteOffset(ref obj, offset)); }
public static void StoreClassField <TValue>(object obj, TValue value, int offset) { Underlying.AddByteOffset(ref TypeHelper.Unbox <TValue>(obj), offset) = value; }
public static TValue LoadClassField <TValue>(object obj, int offset) { return(Underlying.AddByteOffset(ref TypeHelper.Unbox <TValue>(obj), offset)); }