示例#1
0
        protected Type LoadClass(Type baseType, Type interfaceType, Type[] additionalInterfaceTypes)
        {
            String className = interfaceType.FullName + "$" + baseType.Name + "$" + Arrays.GetHashCode(additionalInterfaceTypes);

            if (className.StartsWith("java."))
            {
                className = "ambeth." + className;
            }
            lock (writeLock)
            {
                AccessorClassLoader loader = AccessorClassLoader.Get(interfaceType);
                Type type = loader.LoadClass(className);
                if (type != null)
                {
                    return(type);
                }
                return(CreateGpType(loader, interfaceType, additionalInterfaceTypes, className));
            }
        }
示例#2
0
        protected Type CreateGpType(AccessorClassLoader loader, Type proxyType, Type[] additionalProxyTypes, String className)
        {
            String classNameInternal = className.Replace('.', '/');
            Type   abstractType      = typeof(GCProxy);

            List <Type> interfaceClasses = new List <Type>();

            interfaceClasses.Add(proxyType);
            foreach (Type additionalProxyType in additionalProxyTypes)
            {
                interfaceClasses.Add(additionalProxyType);
            }

            TypeBuilder cw = loader.CreateNewType(TypeAttributes.Public, classNameInternal, abstractType, Type.EmptyTypes);
            {
                ConstructorInfo baseConstructor = abstractType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(Object), typeof(IDisposable) }, null);
                if (baseConstructor == null)
                {
                    throw new Exception("Constructor not found: " + abstractType.FullName);
                }
                ILGenerator mv = cw.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, TypeUtil.GetParameterTypesToTypes(baseConstructor.GetParameters())).GetILGenerator();
                mv.Emit(OpCodes.Ldarg_0);
                mv.Emit(OpCodes.Ldarg_1);
                mv.Emit(OpCodes.Ldarg_2);
                mv.Emit(OpCodes.Call, baseConstructor);
                mv.Emit(OpCodes.Ret);
            }
            {
                ConstructorInfo baseConstructor = abstractType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(IDisposable) }, null);
                if (baseConstructor == null)
                {
                    throw new Exception("Constructor not found: " + abstractType.FullName);
                }
                ILGenerator mv = cw.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, TypeUtil.GetParameterTypesToTypes(baseConstructor.GetParameters())).GetILGenerator();
                mv.Emit(OpCodes.Ldarg_0);
                mv.Emit(OpCodes.Ldarg_1);
                mv.Emit(OpCodes.Call, baseConstructor);
                mv.Emit(OpCodes.Ret);
            }
            MethodInfo targetMethod = ReflectUtil.GetDeclaredMethod(false, typeof(GCProxy), typeof(Object), "ResolveTarget");

            CHashSet <MethodInfo> alreadyImplementedMethods = new CHashSet <MethodInfo>();

            foreach (Type interfaceClass in interfaceClasses)
            {
                MethodInfo[] methods = interfaceClass.GetMethods();
                foreach (MethodInfo method in methods)
                {
                    if (GCProxy.disposeMethod.Equals(method))
                    {
                        // will remain implemented by the GCProxy class
                        continue;
                    }
                    if (!alreadyImplementedMethods.Add(method))
                    {
                        continue;
                    }
                    MethodAttributes attributes = 0;

                    Type[]      paramTypes = TypeUtil.GetParameterTypesToTypes(method.GetParameters());
                    ILGenerator mv         = cw.DefineMethod(method.Name, attributes, CallingConventions.HasThis, method.ReturnType, paramTypes).GetILGenerator();
                    mv.Emit(OpCodes.Ldarg_0);
                    mv.Emit(OpCodes.Callvirt, targetMethod);
                    mv.Emit(OpCodes.Castclass, method.DeclaringType);
                    for (int a = 0, size = paramTypes.Length; a < size; a++)
                    {
                        mv.Emit(OpCodes.Ldarg, a + 1);
                    }
                    mv.Emit(OpCodes.Callvirt, method);
                    mv.Emit(OpCodes.Ret);
                }
            }
            return(loader.GetType(classNameInternal, cw));
        }