コード例 #1
0
        private static void DuplicateMethodSpecial(CsInterface interfaceType, CsMethod csMethod, CsTypeBase intPtrType)
        {
            bool hasComArrayLike = false;
            foreach(var csParameter in csMethod.Parameters)
            {
                if(csParameter.IsInComArrayLike)
                {
                    hasComArrayLike = true;
                    break;
                }
            }

            // Look for at least one parameter ComArray candidate
            if (hasComArrayLike)
            {
                // Create a new method and transforms all array of ComObject to ComArray<ComObject>
                var newMethod = (CsMethod)csMethod.Clone();
                foreach (var csSubParameter in newMethod.Parameters)
                {
                    if (csSubParameter.IsInComArrayLike)
                        csSubParameter.PublicType = new CsComArray((CsInterface)csSubParameter.PublicType);
                }
                interfaceType.Add(newMethod);
            }

            if(hasComArrayLike || csMethod.RequestRawPtr)
            {
                // Create private method with raw pointers for arrays, with all arrays as pure IntPtr
                // In order to be able to generate method taking single element
                var rawMethod = (CsMethod)csMethod.Clone();
                rawMethod.Visibility = Visibility.Private;
                foreach(var csSubParameter in rawMethod.Parameters)
                {
                    if(csSubParameter.IsArray || csSubParameter.IsComObject || csSubParameter.HasPointer)
                    {
                        csSubParameter.PublicType = intPtrType;
                        csSubParameter.IsArray = false;
                        csSubParameter.Attribute = CsParameterAttribute.In;
                    }
                }
                interfaceType.Add(rawMethod);
            }
        }
コード例 #2
0
        /// <summary>
        /// Processes the specified interface type.
        /// </summary>
        /// <param name="interfaceType">Type of the interface.</param>
        public void Process(CsInterface interfaceType )
        {
            if (interfaceType.IsFullyMapped)
                return;

            // Set IsFullyMapped to avoid recursive mapping
            interfaceType.IsFullyMapped = true;

            // var cppInterface = interfaceType.CppElement as CppInterface;
            var cppInterface = (CppInterface)interfaceType.CppElement;

            // Associate Parent
            var parentType = Manager.FindBindType(cppInterface.ParentName);
            if (parentType != null)
            {
                interfaceType.Base = parentType;

                // Process base if it's not mapped already
                if (!parentType.IsFullyMapped)
                    Process(parentType);
            }
            else
            {
                if (!interfaceType.IsCallback)
                    interfaceType.Base = DefaultInterfaceCppObject;
            }

            // Warning, if Guid is null we need to recover it from a declared GUID
            if (string.IsNullOrEmpty(cppInterface.Guid))
            {
                // Go up to the root base interface
                var rootBase = parentType;
                while (rootBase != null && rootBase is CsInterface && ((CsInterface)rootBase).Base != null)
                    rootBase = ((CsInterface) rootBase).Base;

                // look for GUID only for ComObjects
                var cppGuid = cppInterface.ParentInclude.Find<CppGuid>("^IID_" + cppInterface.Name + "$").FirstOrDefault();
                if (cppGuid == null)
                {
                    // If Guid == null && BaseRoot != null && BaseRoot is a ComObject
                    // then we probably missed a guid
                    if (rootBase != null && rootBase.QualifiedName == Global.Name + ".ComObject")
                        Logger.Warning("cannot find GUID");
                } 
                else
                    interfaceType.Guid = cppGuid.Guid.ToString();
            }

            // Handle Methods
            var generatedMethods = new List<CsMethod>();
            var intPtrType = Manager.ImportType(typeof(IntPtr));
            foreach (var cppMethod in cppInterface.Methods)
            {
                var cSharpMethod = (CsMethod)MethodTranform.Prepare(cppMethod);
                generatedMethods.Add(cSharpMethod);
                interfaceType.Add(cSharpMethod);

                MethodTranform.Process(cSharpMethod);

                // Add specialized method for ComArray
                DuplicateMethodSpecial(interfaceType, cSharpMethod, intPtrType);

                //MapMethod(cSharpMethod);
                //RegisterNativeInterop(cSharpMethod);

				// Allow overloads by changing the name to <name>#
				string origCppName = cppInterface.Name + "::" + cppMethod.Name;
				string chosenCppName = origCppName;
				for (int i = 0; Manager.FindBindType(chosenCppName) != null; i++)
					chosenCppName = origCppName + i.ToString();
					
                Manager.BindType(chosenCppName, cSharpMethod);
            }

            // Dispatch method to inner interface if any
            var mapInnerInterface = new Dictionary<string, CsInterface>();

            // Make a copy of the methods
            var methods = interfaceType.Methods.ToList();
            foreach (var csMethod in methods)
            {
                string cppName = interfaceType.CppElementName + "::" + csMethod.CppElement.Name;
                foreach (var keyValuePair in _mapMoveMethodToInnerInterface)
                {
                    if (keyValuePair.Key.Match(cppName).Success)
                    {
                        string innerInterfaceName = keyValuePair.Value.InnerInterface;
                        string parentInterfaceName = keyValuePair.Value.InheritedInterfaceName;

                        CsInterface innerCsInterface;
                        CsInterface parentCsInterface = null;

                        if (parentInterfaceName != null)
                        {
                            if (!mapInnerInterface.TryGetValue(parentInterfaceName, out parentCsInterface))
                            {
                                parentCsInterface = new CsInterface(null) { Name = parentInterfaceName };
                                mapInnerInterface.Add(parentInterfaceName, parentCsInterface);
                            }
                        }

                        if (!mapInnerInterface.TryGetValue(innerInterfaceName, out innerCsInterface))
                        {
                            // TODO custom cppInterface?
                            innerCsInterface = new CsInterface(cppInterface)
                                { Name = innerInterfaceName, PropertyAccesName = keyValuePair.Value.PropertyAccessName, Base = parentCsInterface ?? DefaultInterfaceCppObject };

                            // Add inner interface to root interface
                            interfaceType.Add(innerCsInterface);
                            interfaceType.Parent.Add(innerCsInterface);

                            // Move method to inner interface
                            mapInnerInterface.Add(innerInterfaceName, innerCsInterface);
                        }

                        interfaceType.Remove(csMethod);
                        innerCsInterface.Add(csMethod);
                        break;
                    }
                }
            }

            // Remove dispatched methods from outer interface
            //foreach (var innerInterface in mapInnerInterface)
            //{
            //    foreach (var method in innerInterface.Value.Methods)
            //        cppInterface.Remove(method.CppElement);
            //}

            // If interfaceType is DualCallback, then need to generate a default implem
            if (interfaceType.IsDualCallback)
            {
                var tagForInterface = cppInterface.GetTagOrDefault<MappingRule>();
                var nativeCallback = new CsInterface(interfaceType.CppElement as CppInterface)
                                         {
                                             Name = interfaceType.Name + "Native",
                                             Visibility = Visibility.Internal
                                         };

                // Update nativeCallback from tag
                if (tagForInterface != null)
                {
                    if (tagForInterface.NativeCallbackVisibility.HasValue)
                        nativeCallback.Visibility = tagForInterface.NativeCallbackVisibility.Value;
                    if (tagForInterface.NativeCallbackName != null)
                        nativeCallback.Name = tagForInterface.NativeCallbackName;
                }

                nativeCallback.Base = interfaceType.Base;

                if (nativeCallback.IsBaseComObject)
                {
                    nativeCallback.Base = DefaultComObjectCallback;
                }

                // If Parent is a DualInterface, then inherit from Default Callback
                if (interfaceType.Base is CsInterface)
                {
                    var parentInterface = interfaceType.Base as CsInterface;
                    if (parentInterface.IsDualCallback)
                        nativeCallback.Base = parentInterface.NativeImplem;
                }

                nativeCallback.IBase = interfaceType;
                interfaceType.NativeImplem = nativeCallback;

                foreach (var innerElement in interfaceType.Items)
                {
                    if (innerElement is CsMethod)
                    {
                        var method = (CsMethod)innerElement;
                        var newCsMethod = (CsMethod)method.Clone();
                        var tagForMethod = method.CppElement.GetTagOrDefault<MappingRule>();
                        bool keepMethodPublic = tagForMethod.IsKeepImplementPublic.HasValue && tagForMethod.IsKeepImplementPublic.Value;
                        if (!keepMethodPublic)
                        {
                            newCsMethod.Visibility = Visibility.Internal;
                            newCsMethod.Name = newCsMethod.Name + "_";
                        }
                        nativeCallback.Add(newCsMethod);
                    }
                    else
                    {
                        Logger.Warning("Unhandled innerElement {0} for DualCallbackInterface {1}", innerElement, interfaceType.Name);
                    }
                }
                nativeCallback.IsCallback = false;
                nativeCallback.IsDualCallback = true;
                interfaceType.Parent.Add(nativeCallback);
            }
            else
            {
                // If interface is a callback and parent is ComObject, then remove it
                var parentInterface = interfaceType.Base as CsInterface;
                if (parentInterface != null && parentInterface.IsDualCallback)
                {
                    interfaceType.Base = parentInterface.NativeImplem;
                }
                else
                {
                    // Refactor Properties
                    CreateProperties(generatedMethods);
                }
            }

            // If interface is a callback and parent is ComObject, then remove it
            if (interfaceType.IsCallback )
            {
                if (interfaceType.IsBaseComObject)
                    interfaceType.Base = null;
                if (interfaceType.Base == null)
                    interfaceType.Base = DefaultCallbackable;
            }
        }
コード例 #3
0
ファイル: InterfaceTransform.cs プロジェクト: Ziriax/SharpDX
 private static void CreateMethodsForComArrayMethod(CsInterface interfaceType, CsMethod csMethod)
 {
     foreach (var csParameter in csMethod.Parameters)
     {
         // Look for at least one parameter ComArray candidate
         if (csParameter.IsInComArrayLike)
         {
             // Create a new method and transforms all array of ComObject to ComArray<ComObject>
             var newMethod = (CsMethod)csMethod.Clone();
             foreach (var csSubParameter in newMethod.Parameters)
             {
                 if (csSubParameter.IsInComArrayLike)
                     csSubParameter.PublicType = new CsComArray((CsInterface)csSubParameter.PublicType);
             }
             interfaceType.Add(newMethod);
             break;
         }
     }
 }