Пример #1
0
        /// <summary>
        /// Get the event delegate for specified method in the source interface. Create a new one if necessary
        /// </summary>
        /// <param name="index">Function index</param>
        /// <returns>The delegate type</returns>
        public Type GetEventDelegate(InterfaceMemberInfo memberInfo)
        {
            TypeInfo type = memberInfo.RefTypeInfo;

            using (TypeAttr attr = type.GetTypeAttr())
            {
                // Create m_delegateTypes on demand
                if (m_delegateTypes == null)
                {
                    m_delegateTypes = new Dictionary <InterfaceMemberInfo, Type>();
                }

                //
                // Check if we already have a delegate type for method n
                //
                if (!m_delegateTypes.ContainsKey(memberInfo))
                {
                    //
                    // If not, create a new delegate
                    //
                    FuncDesc func = type.GetFuncDesc(memberInfo.Index);

                    string eventName    = type.GetDocumentation(func.memid);
                    string delegateName = m_info.GetRecommendedManagedName(m_convInterface.RefTypeInfo, ConvType.Interface, true) + "_" + type.GetDocumentation(func.memid) + "EventHandler";

                    // Deal with name collisions
                    delegateName = m_info.GetUniqueManagedName(delegateName);

                    TypeBuilder delegateTypeBuilder = m_info.ModuleBuilder.DefineType(
                        delegateName,
                        TypeAttributes.Public | TypeAttributes.Sealed,
                        typeof(MulticastDelegate)
                        );

                    // Create constructor for the delegate
                    ConstructorBuilder delegateCtorBuilder = delegateTypeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[] { typeof(Object), typeof(UIntPtr) });
                    delegateCtorBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);

                    // Create methods for the delegate
                    InterfaceInfo interfaceInfoForDelegate = new InterfaceInfo(m_info, delegateTypeBuilder, false, type, attr, false, true);
                    interfaceInfoForDelegate.AllowNewEnum = !m_convInterface.ImplementsIEnumerable;
                    ConvCommon.CreateMethodForDelegate(interfaceInfoForDelegate, func, memberInfo.Index);

                    // Emit ComVisibleAttribute(false)
                    delegateTypeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComVisible(false));

                    // Emit TypeLibTypeAttribute(TypeLibTypeFlags.FHidden) to hide it from object browser in VB
                    delegateTypeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType(TypeLibTypeFlags.FHidden));

                    // Create the delegate
                    m_delegateTypes[memberInfo] = delegateTypeBuilder.CreateType();
                }
            }

            return(m_delegateTypes[memberInfo]);
        }
Пример #2
0
        /// <summary>
        /// Create the event interface
        /// </summary>
        public override void OnCreate()
        {
            if (m_type != null)
            {
                return;
            }

            string name = m_convInterface.ManagedName;

            m_convInterface.Create();

            using (TypeAttr attr = m_convInterface.RefTypeInfo.GetTypeAttr())
            {
                //
                // Emit attributes
                //

                //
                // Emit [ComEventInterfaceAttribute(...)]
                //
                ConstructorInfo ctorComEventInterface = typeof(ComEventInterfaceAttribute).GetConstructor(
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                    null,
                    new Type[] { typeof(Type), typeof(Type) },
                    null);

                //
                // Build the blob manually before creating the event interface / provider types.
                // We only need to give the name of the types, in order to simplify creation logic and avoid dependency
                //
                CustomAttributeBlobBuilder blobBuilder = new CustomAttributeBlobBuilder();

                string eventInterfaceFullyQualifiedName = name;
                if (m_convInterface.ConvScope == ConvScope.External)
                {
                    eventInterfaceFullyQualifiedName = m_convInterface.ManagedType.AssemblyQualifiedName;
                }

                blobBuilder.AddFixedArg(eventInterfaceFullyQualifiedName);                      // source interface

                // Handle event provider name generation collision scenario
                m_eventProviderName = m_info.GetUniqueManagedName(
                    m_info.GetRecommendedManagedName(m_convInterface.RefTypeInfo, ConvType.Interface, true) + "_EventProvider");

                blobBuilder.AddFixedArg(m_eventProviderName);   // corresponding event provider
                m_typeBuilder.SetCustomAttribute(ctorComEventInterface, blobBuilder.GetBlob());

                //
                // Emit ComVisibleAttribute(false)
                //
                m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComVisible(false));

                //
                // Emit TypeLibTypeAttribute for TYPEFLAG_FHIDDEN
                //
                m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType(TypeLibTypeFlags.FHidden));

                bool isConversionLoss = false;

                //
                // Verify if the type has any properties
                //
                Type interfaceType = m_convInterface.RealManagedType;
                if (interfaceType.GetProperties().Length > 0)
                {
                    // Emit a warning and we'll skip the properties
                    m_info.ReportEvent(
                        WarningCode.Wrn_NoPropsInEvents,
                        Resource.FormatString("Wrn_NoPropsInEvents", RefTypeInfo.GetDocumentation()));

                    isConversionLoss = true;
                }

                //
                // Create event interface
                //

                InterfaceInfo eventInterfaceInfo = new InterfaceInfo(m_info, m_typeBuilder, false, m_convInterface.RefTypeInfo, attr, false, true);

                ConvCommon.CreateEventInterfaceCommon(eventInterfaceInfo);
                isConversionLoss |= eventInterfaceInfo.IsConversionLoss;

                //
                // Emit ComConversionLossAttribute if necessary
                //
                if (eventInterfaceInfo.IsConversionLoss)
                {
                    m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComConversionLoss());
                }
            }

            m_type = m_typeBuilder.CreateType();
        }