Exemplo n.º 1
0
        static CcwMethodInfo CreateCcwMethod(ComMethodInfo comMethodInfo, TypeBuilder typeBuilder,
                                             Utils.UniqueNameGenerator methodNameUniqifier)
        {
            var methodInfo         = comMethodInfo.MethodInfo;
            var methodNameTemplate = methodInfo.Name;
            var methodName         = methodNameUniqifier.Uniquify(methodNameTemplate);
            var paramTypes         = new List <Type>();

            paramTypes.Add(typeof(IntPtr));
            paramTypes.AddRange(comMethodInfo.ParameterInfos.Select((p) => p.IsOut ?
                                                                    p.ValueMarshaller.NativeParameterType.MakePointerType() : p.ValueMarshaller.NativeParameterType));
            var methodBuilder = typeBuilder.DefineMethod(methodName,
                                                         MethodAttributes.HideBySig | MethodAttributes.Static, CallingConventions.Standard,
                                                         comMethodInfo.NativeReturnType,
                                                         paramTypes.ToArray());

            methodBuilder.DefineParameter(1, ParameterAttributes.In,
                                          "this");

            // define a method
            foreach (var parameter in methodInfo.GetParameters())
            {
                methodBuilder.DefineParameter(parameter.Position + 2,
                                              parameter.Attributes, parameter.Name);
            }

            CreateCcwMethodBody(comMethodInfo, methodBuilder);

            return(new CcwMethodInfo()
            {
                methodBuilder = methodBuilder,
                parameterTypes = paramTypes.ToArray()
            });
        }
Exemplo n.º 2
0
        static void ImplementFieldGetter(TypeBuilder typeBuilder, FieldInfo fieldInfo, PropertyInfo genericPropertyInfo, MethodInfo getterMethodInfo,
                                         Utils.UniqueNameGenerator methodNameUniqifier)
        {
            var propNameTemplate = getterMethodInfo.DeclaringType.Name + "." + genericPropertyInfo.Name;
            var propName         = methodNameUniqifier.Uniquify(propNameTemplate);
            var prop             = typeBuilder.DefineProperty(propName, PropertyAttributes.None,
                                                              getterMethodInfo.ReturnType, new Type[] { });

            var methodNameTemplate = getterMethodInfo.DeclaringType.Name + "." + getterMethodInfo.Name;
            var methodName         = methodNameUniqifier.Uniquify(methodNameTemplate);
            var methodBuilder      = typeBuilder.DefineMethod(methodName,
                                                              MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
                                                              CallingConventions.Standard,
                                                              getterMethodInfo.ReturnType,
                                                              new Type[] { });

            typeBuilder.DefineMethodOverride(methodBuilder, getterMethodInfo);

            var gen = methodBuilder.GetILGenerator();

            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldfld, fieldInfo);
            gen.Emit(OpCodes.Ret);

            prop.SetGetMethod(methodBuilder);
        }
Exemplo n.º 3
0
        static void DefineRcwClass(InterfaceInfo interfaceInfo, TypeBuilder typeBuilder)
        {
            var type = typeBuilder;

            var nativeObjectType     = typeof(INativeObject <>).GetTypeInfo().MakeGenericType(type);
            var nativeObjectTypeInfo = nativeObjectType.GetTypeInfo();

            typeBuilder.AddInterfaceImplementation(nativeObjectType);

            foreach (var theInterface in interfaceInfo.AllImplementedInterfaces)
            {
                typeBuilder.AddInterfaceImplementation(theInterface);
            }

            FieldInfo interfacePtrField = typeBuilder.DefineField("interfacePtr", typeof(IntPtr), 0);
            FieldInfo unknownPtrField   = typeBuilder.DefineField("iUnknownPtr", typeof(IntPtr), 0);

            // generate constructor
            var ctor = CreateRcwConstructor(typeBuilder, interfacePtrField, unknownPtrField);

            // generate finalizer
            CreateRcwFinalizer(typeBuilder);

            // generate factory
            CreateRcwFactoryMethod(typeBuilder, ctor);

            var methodNameUniqifier = new Utils.UniqueNameGenerator();

            methodNameUniqifier.Uniquify("interfacePtr");
            methodNameUniqifier.Uniquify("iUnknownPtr");
            methodNameUniqifier.Uniquify("Finalize");
            methodNameUniqifier.Uniquify("Create");
            foreach (var method in interfaceInfo.ComMethodInfos)
            {
                CreateRcwMethod(method, typeBuilder, interfacePtrField, methodNameUniqifier);
            }

            // implement INativeObject
            ImplementFieldGetter(typeBuilder, interfacePtrField,
                                 nativeInterfacePtrProp, TypeBuilder.GetMethod(nativeObjectType, nativeInterfacePtrProp.GetMethod),
                                 methodNameUniqifier);
            ImplementFieldGetter(typeBuilder, unknownPtrField,
                                 nativeIUnknownPtrProp, TypeBuilder.GetMethod(nativeObjectType, nativeIUnknownPtrProp.GetMethod),
                                 methodNameUniqifier);
            ImplementInterfaceProperty(typeBuilder,
                                       interfaceProp, TypeBuilder.GetMethod(nativeObjectType, interfaceProp.GetMethod),
                                       methodNameUniqifier);
        }
Exemplo n.º 4
0
        static void DefineCcwClass(InterfaceInfo interfaceInfo, TypeBuilder typeBuilder)
        {
            var type = typeBuilder;

            var uniqifier = new Utils.UniqueNameGenerator();

            uniqifier.Uniquify("Create"); // reserve

            var methods = new List <CcwMethodInfo>();

            foreach (var method in interfaceInfo.ComMethodInfos)
            {
                methods.Add(CreateCcwMethod(method, typeBuilder, uniqifier));
            }

            CreateCcwFactoryMethod(typeBuilder, methods.ToArray(), uniqifier);
        }
Exemplo n.º 5
0
        static void CreateRcwMethod(ComMethodInfo comMethodInfo, TypeBuilder typeBuilder,
                                    FieldInfo ptrFieldInfo, Utils.UniqueNameGenerator methodNameUniqifier)
        {
            var methodInfo         = comMethodInfo.MethodInfo;
            var methodNameTemplate = comMethodInfo.MethodInfo.DeclaringType.Name + "." + methodInfo.Name;
            var methodName         = methodNameUniqifier.Uniquify(methodNameTemplate);
            var methodBuilder      = typeBuilder.DefineMethod(methodName,
                                                              MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.Standard,
                                                              methodInfo.ReturnType,
                                                              methodInfo.GetParameters().Select((p) => p.ParameterType).ToArray());

            typeBuilder.DefineMethodOverride(methodBuilder, methodInfo);

            // define a method
            foreach (var parameter in methodInfo.GetParameters())
            {
                methodBuilder.DefineParameter(parameter.Position + 1,
                                              parameter.Attributes, parameter.Name);
            }

            CreateRCWMethodBody(comMethodInfo, ptrFieldInfo, methodBuilder);
        }
Exemplo n.º 6
0
        static MethodBuilder CreateCcwFactoryMethod(TypeBuilder typeBuilder, CcwMethodInfo[] vtable, Utils.UniqueNameGenerator uniqifier)
        {
            var nativeObjectType = typeof(INativeObject <>).GetTypeInfo().MakeGenericType(typeBuilder);
            var methodBuilder    = typeBuilder.DefineMethod("Create",
                                                            MethodAttributes.Static | MethodAttributes.Public | MethodAttributes.HideBySig,
                                                            CallingConventions.Standard,
                                                            typeof(IntPtr[]), new Type[] { });

            methodBuilder.SetCustomAttribute(securityCriticalAttributeCab);

            var gen = methodBuilder.GetILGenerator();

            gen.Emit(OpCodes.Ldc_I4, vtable.Length);
            gen.Emit(OpCodes.Newarr, typeof(IntPtr));
            for (int i = 0; i < vtable.Length; ++i)
            {
                var ccwMethodInfo = vtable[i];

                gen.Emit(OpCodes.Dup);
                gen.Emit(OpCodes.Ldc_I4, i);
                gen.Emit(OpCodes.Ldftn, ccwMethodInfo.methodBuilder);
                gen.Emit(OpCodes.Stelem, typeof(IntPtr));

                // add MonoPInvokeCallbackAttribute so this method is included in
                // full AOT

                /*var mpca = new CustomAttributeBuilder(typeof(MonoPInvokeCallbackAttribute)
                 *                      .GetTypeInfo()
                 *                      .DeclaredConstructors.First((ctor2) => ctor2.GetParameters().Length == 1),
                 *                              new object[] { delegateType });
                 *              ccwMethodInfo.methodBuilder.SetCustomAttribute(mpca);
                 *
                 *              delegateType.CreateTypeInfo();*/
            }

            gen.Emit(OpCodes.Ret);

            return(methodBuilder);
        }