public object Invoke(int MethodId, params object[] args) { if (IsDisposed) { throw new Exception("The shared class is disposed"); } SharedMethod method = GetMethod(MethodId); lock (method.InvokeLocky) { ReturnResult ret = method.Invoke(args) as ReturnResult; if (ret != null) { if (ret.ExceptionOccured) { throw new Exception(ret.exceptionMessage); } return(ret.ReturnValue); } return(null); } throw new Exception("Method not found"); }
internal SharedDelegate(MethodInfo info, SharedClass sharedClass, Type DelegateType, int DelegateId, Delegate Delegate, int MethodId) { this.sharedMethod = new SharedMethod(info, sharedClass, true, DelegateId); this.DelegateType = DelegateType; this.Delegate = Delegate; this.sharedMethod.MethodId = MethodId; }
/// <summary> </summary> /// <param name="Object">The Class object to share with others</param> /// <param name="RemoteInitialize">False: The class will be initialized locally using the "ClassArgs" objects, /// True: The remote client will give the ClassArgs to use for initializing the object and will ignore the local argument objects</param> /// <param name="ClassArgs">The objects to initialize the class with</param> internal SharedClass(Type ClassType, AClient connection, bool RemoteInitialize = false, params object[] ClassArgs) { if (ClassType == null) throw new ArgumentNullException("Object"); if (!ClassType.IsClass) throw new Exception("Object is not a class"); this._Methods = new SortedList<string, List<SharedMethod>>(); this.BaseClassType = ClassType; this.BaseClassTypeArgs = ClassArgs; if (this.BaseClassTypeArgs == null) this.BaseClassTypeArgs = new object[0]; this.Name = ClassType.Name; this.connection = connection; this.ConstructorTypes = new List<Type[]>(); this.RemoteInitialize = RemoteInitialize; List<SharedMethod> methods = new List<SharedMethod>(); foreach (MethodInfo m in ClassType.GetMethods()) { if (!m.IsPublic || m.GetCustomAttributes(typeof(RemoteExecutionAttribute), false).Length == 0 && m.GetCustomAttributes(typeof(UncheckedRemoteExecutionAttribute), false).Length == 0) continue; SharedMethod sharedMethod = new SharedMethod(m, this); int token = m.MetadataToken; if (!_Methods.ContainsKey(m.Name)) _Methods.Add(m.Name, new List<SharedMethod>()); _Methods[m.Name].Add(sharedMethod); methods.Add(sharedMethod); sharedMethod.MethodId = methods.Count; } this.Methods = methods.ToArray(); foreach (ConstructorInfo m in ClassType.GetConstructors()) { if (!m.IsStatic && m.IsPublic && m.GetCustomAttributes(typeof(RemoteConstructorAttribute), false).Length > 0) { List<Type> list = new List<Type>(); foreach(ParameterInfo param in m.GetParameters()) list.Add(param.ParameterType); ConstructorTypes.Add(list.ToArray()); } } }
public object Invoke(string MethodName, params object[] args) { SharedMethod method = null; if ((method = GetMethod(MethodName, args)) != null) { lock (method.InvokeLocky) { ReturnResult ret = method.Invoke(args) as ReturnResult; if (ret != null) { if (ret.ExceptionOccured) { throw new Exception(ret.exceptionMessage); } return(ret.ReturnValue); } return(null); } } throw new Exception("Method not found"); }
private void DuplicateMethods(TypeBuilder typeBuilder, Type target, FieldBuilder fb, SharedClass sharedClass) { foreach (MethodInfo m in target.GetMethods()) { /*if ((m.GetCustomAttributes(typeof(RemoteExecutionAttribute), false).Length == 0 && * m.GetCustomAttributes(typeof(UncheckedRemoteExecutionAttribute), false).Length == 0) && * m.Name != "Dispose") * { * continue; * }*/ Type[] ArgumentTypes = GetParameterTypes(m.GetParameters()); MethodBuilder builder = typeBuilder.DefineMethod(m.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, m.CallingConvention, m.ReturnType, ArgumentTypes); typeBuilder.DefineMethodOverride(builder, m); //builder.CreateMethodBody(null, 0); ILGenerator gen = builder.GetILGenerator(); MethodInfo SharedCall = typeof(SharedClass).GetMethod("Invoke", new Type[] { typeof(int), typeof(object[]) }); SharedMethod sharedMethod = sharedClass.GetMethod(m.Name, ArgumentTypes); LocalBuilder lb = gen.DeclareLocal(typeof(object[])); if (sharedMethod == null) { throw new Exception("Missing a method \"" + m.Name + "\" check your shared class!"); } //load $haredClass gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, fb); gen.Emit(OpCodes.Ldc_I4, sharedMethod.MethodId); //gen.Emit(OpCodes.Ldstr, m.Name); //init local array gen.Emit(OpCodes.Ldc_I4, ArgumentTypes.Length); gen.Emit(OpCodes.Newarr, typeof(object)); gen.Emit(OpCodes.Stloc_0); for (int i = 0; i < ArgumentTypes.Length; i++) { gen.Emit(OpCodes.Ldloc_0); gen.Emit(OpCodes.Ldc_I4, i); gen.Emit(OpCodes.Ldarg, i + 1); if (ArgumentTypes[i].IsByRef) { //remove & at the end since ref/out adds & at the end of the argument ArgumentTypes[i] = Type.GetType(ArgumentTypes[i].FullName.Substring(0, ArgumentTypes[i].FullName.Length - 1)); } gen.Emit(OpCodes.Box, ArgumentTypes[i]); gen.Emit(OpCodes.Stelem_Ref); } gen.Emit(OpCodes.Ldloc_0); gen.Emit(OpCodes.Callvirt, SharedCall); bool isInt = m.ReturnType.IsAssignableFrom(typeof(System.Int32)) || m.ReturnType.IsAssignableFrom(typeof(System.UInt32)) || m.ReturnType.IsAssignableFrom(typeof(System.Boolean)) || m.ReturnType.IsAssignableFrom(typeof(System.Int64)) || m.ReturnType.IsAssignableFrom(typeof(System.UInt64)); if (m.ReturnType.FullName != "System.Void" && !isInt) { gen.Emit(OpCodes.Box, m.ReturnType); } else if (m.ReturnType.FullName == "System.Void") //no return { gen.Emit(OpCodes.Pop); } else if (isInt) { gen.Emit(OpCodes.Unbox, m.ReturnType); gen.Emit(OpCodes.Ldobj, m.ReturnType); } gen.Emit(OpCodes.Ret); } }
/// <summary> </summary> /// <param name="Object">The Class object to share with others</param> /// <param name="RemoteInitialize">False: The class will be initialized locally using the "ClassArgs" objects, /// True: The remote client will give the ClassArgs to use for initializing the object and will ignore the local argument objects</param> /// <param name="ClassArgs">The objects to initialize the class with</param> /// <param name="MaxInitializations">The maximum count that the class can be shared </param> internal SharedClass(string SharedName, Type ClassType, LiteCodeClient Client, bool RemoteInitialize = false, int MaxInitializations = 100, params object[] ClassArgs) { if (ClassType == null) { throw new ArgumentNullException("Object"); } if (!ClassType.IsClass) { throw new Exception("Object is not a class"); } this._Methods = new SortedList <string, List <SharedMethod> >(); this.BaseClassType = ClassType; this.BaseClassTypeArgs = ClassArgs; if (this.BaseClassTypeArgs == null) { this.BaseClassTypeArgs = new object[0]; } this.TypeName = ClassType.FullName; this.SharedName = SharedName; this.Client = Client; this.ConstructorTypes = new List <Type[]>(); this.RemoteInitialize = RemoteInitialize; this.MaxInitializations = MaxInitializations; foreach (MethodInfo m in ClassType.GetMethods()) { if (!m.IsPublic || m.GetCustomAttributes(typeof(RemoteExecutionAttribute), false).Length == 0 && m.GetCustomAttributes(typeof(UncheckedRemoteExecutionAttribute), false).Length == 0) { continue; } SharedMethod sharedMethod = new SharedMethod(m, this); if (!_Methods.ContainsKey(m.Name)) { _Methods.Add(m.Name, new List <SharedMethod>()); } _Methods[m.Name].Add(sharedMethod); } //set Method Id int methodId = 0; for (int i = 0; i < _Methods.Count; i++) { for (int j = 0; j < _Methods.Values[i].Count; j++) { _Methods.Values[i][j].MethodId = ++methodId; } } foreach (ConstructorInfo m in ClassType.GetConstructors()) { if (!m.IsStatic && m.IsPublic && m.GetCustomAttributes(typeof(RemoteConstructorAttribute), false).Length > 0) { List <Type> list = new List <Type>(); foreach (ParameterInfo param in m.GetParameters()) { list.Add(param.ParameterType); } ConstructorTypes.Add(list.ToArray()); } } }
/// <summary> </summary> /// <param name="Object">The Class object to share with others</param> /// <param name="RemoteInitialize">False: The class will be initialized locally using the "ClassArgs" objects, /// True: The remote client will give the ClassArgs to use for initializing the object and will ignore the local argument objects</param> /// <param name="ClassArgs">The objects to initialize the class with</param> internal SharedClass(Type ClassType, AClient connection, bool RemoteInitialize = false, params object[] ClassArgs) { if (ClassType == null) { throw new ArgumentNullException("Object"); } if (!ClassType.IsClass) { throw new Exception("Object is not a class"); } this._Methods = new SortedList <string, List <SharedMethod> >(); this.BaseClassType = ClassType; this.BaseClassTypeArgs = ClassArgs; if (this.BaseClassTypeArgs == null) { this.BaseClassTypeArgs = new object[0]; } this.Name = ClassType.Name; this.connection = connection; this.ConstructorTypes = new List <Type[]>(); this.RemoteInitialize = RemoteInitialize; List <SharedMethod> methods = new List <SharedMethod>(); foreach (MethodInfo m in ClassType.GetMethods()) { if (!m.IsPublic || m.GetCustomAttributes(typeof(RemoteExecutionAttribute), false).Length == 0 && m.GetCustomAttributes(typeof(UncheckedRemoteExecutionAttribute), false).Length == 0) { continue; } SharedMethod sharedMethod = new SharedMethod(m, this); int token = m.MetadataToken; if (!_Methods.ContainsKey(m.Name)) { _Methods.Add(m.Name, new List <SharedMethod>()); } _Methods[m.Name].Add(sharedMethod); methods.Add(sharedMethod); sharedMethod.MethodId = methods.Count; } this.Methods = methods.ToArray(); foreach (ConstructorInfo m in ClassType.GetConstructors()) { if (!m.IsStatic && m.IsPublic && m.GetCustomAttributes(typeof(RemoteConstructorAttribute), false).Length > 0) { List <Type> list = new List <Type>(); foreach (ParameterInfo param in m.GetParameters()) { list.Add(param.ParameterType); } ConstructorTypes.Add(list.ToArray()); } } }