コード例 #1
0
        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);
        }
コード例 #2
0
        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);
                }
            }
        }
コード例 #3
0
        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 });
                    }
                }
            }
        }
コード例 #4
0
 public ref TValue GetReference(object obj)
 => ref Underlying.AddByteOffset(ref TypeHelper.Unbox <TValue>(obj), offset);
コード例 #5
0
 /// <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);
コード例 #6
0
 public static void StoreStructField <TValue>(ref TValue obj, TValue value, int offset)
 {
     Underlying.AddByteOffset(ref obj, offset) = value;
 }
コード例 #7
0
 public static TValue LoadStructField <TValue>(ref TValue obj, int offset)
 {
     return(Underlying.AddByteOffset(ref obj, offset));
 }
コード例 #8
0
 public static void StoreClassField <TValue>(object obj, TValue value, int offset)
 {
     Underlying.AddByteOffset(ref TypeHelper.Unbox <TValue>(obj), offset) = value;
 }
コード例 #9
0
 public static TValue LoadClassField <TValue>(object obj, int offset)
 {
     return(Underlying.AddByteOffset(ref TypeHelper.Unbox <TValue>(obj), offset));
 }