/// <summary> /// Processes the specified method. /// </summary> /// <param name="method">The method.</param> private void Process(CsMethod method) { var cppMethod = (CppMethod)method.CppElement; method.Name = NamingRules.Rename(cppMethod); method.Offset = cppMethod.Offset; // For methods, the tag "type" is only used for return type // So we are overriding the return type here var tag = cppMethod.GetTagOrDefault<MappingRule>(); if (tag.MappingType != null) cppMethod.ReturnType.Tag = new MappingRule() { MappingType = tag.MappingType }; // Apply any offset to the method's vtable method.Offset += tag.LayoutOffsetTranslate; // Get the inferred return type method.ReturnType = Manager.GetCsType<CsMarshalBase>(cppMethod.ReturnType); // Hide return type only if it is a HRESULT and AlwaysReturnHResult is false if (method.CheckReturnType && method.ReturnType.PublicType != null && method.ReturnType.PublicType.QualifiedName == "SharpDX.Result") { method.HideReturnType = !method.AlwaysReturnHResult; } // Iterates on parameters to convert them to C# parameters foreach (var cppParameter in cppMethod.Parameters) { var cppAttribute = cppParameter.Attribute; var paramTag = cppParameter.GetTagOrDefault<MappingRule>(); bool hasArray = cppParameter.IsArray || ((cppAttribute & ParamAttribute.Buffer) != 0); bool hasParams = (cppAttribute & ParamAttribute.Params) == ParamAttribute.Params; bool isOptional = (cppAttribute & ParamAttribute.Optional) != 0; var paramMethod = Manager.GetCsType<CsParameter>(cppParameter); paramMethod.Name = NamingRules.Rename(cppParameter); bool hasPointer = paramMethod.HasPointer; var publicType = paramMethod.PublicType; var marshalType = paramMethod.MarshalType; CsParameterAttribute parameterAttribute = CsParameterAttribute.In; if (hasArray) hasPointer = true; // -------------------------------------------------------------------------------- // Pointer - Handle special cases // -------------------------------------------------------------------------------- if (hasPointer) { marshalType = Manager.ImportType(typeof(IntPtr)); // -------------------------------------------------------------------------------- // Handling Parameter Interface // -------------------------------------------------------------------------------- if (publicType is CsInterface) { // Force Interface** to be ParamAttribute.Out when None if (cppAttribute == ParamAttribute.In) { if (cppParameter.Pointer == "**") cppAttribute = ParamAttribute.Out; } if ( (cppAttribute & ParamAttribute.In) != 0 || (cppAttribute & ParamAttribute.InOut) != 0) { parameterAttribute = CsParameterAttribute.In; // Force all array of interface to support null if (hasArray) { isOptional = true; } // If Interface is a callback, use IntPtr as a public marshalling type CsInterface publicCsInterface = (CsInterface)publicType; if (publicCsInterface.IsCallback) { publicType = Manager.ImportType(typeof(IntPtr)); // By default, set the Visibility to internal for methods using callbacks // as we need to provide user method. Don't do this on functions as they // are already hidden by the container if (!(method is CsFunction)) { method.Visibility = Visibility.Internal; method.Name = method.Name + "_"; } } } //else if ((cppParameter.Attribute & ParamAttribute.InOut) != 0) // parameterAttribute = method.ParameterAttribute.Ref; else if ((cppAttribute & ParamAttribute.Out) != 0) parameterAttribute = CsParameterAttribute.Out; } else { // If a pointer to array of bool are handle as array of int if (paramMethod.IsBoolToInt && (cppAttribute & ParamAttribute.Buffer) != 0) publicType = Manager.ImportType(typeof(int)); // -------------------------------------------------------------------------------- // Handling Parameter Interface // -------------------------------------------------------------------------------- if ((cppAttribute & ParamAttribute.In) != 0) { parameterAttribute = publicType.Type == typeof(IntPtr) || publicType.Name == Global.Name + ".FunctionCallback" || publicType.Type == typeof(string) ? CsParameterAttribute.In : CsParameterAttribute.RefIn; } else if ((cppAttribute & ParamAttribute.InOut) != 0) { if ((cppAttribute & ParamAttribute.Optional) != 0) { publicType = Manager.ImportType(typeof(IntPtr)); parameterAttribute = CsParameterAttribute.In; } else { parameterAttribute = CsParameterAttribute.Ref; } } else if ((cppAttribute & ParamAttribute.Out) != 0) parameterAttribute = CsParameterAttribute.Out; // Handle void* with Buffer attribute if (cppParameter.TypeName == "void" && (cppAttribute & ParamAttribute.Buffer) != 0) { hasArray = false; // arrayDimension = 0; parameterAttribute = CsParameterAttribute.In; } else if (publicType.Type == typeof(string) && (cppAttribute & ParamAttribute.Out) != 0) { publicType = Manager.ImportType(typeof(IntPtr)); parameterAttribute = CsParameterAttribute.In; hasArray = false; } else if (publicType is CsStruct && (parameterAttribute == CsParameterAttribute.Out || hasArray || parameterAttribute == CsParameterAttribute.RefIn || parameterAttribute == CsParameterAttribute.Ref)) { // Set IsOut on structure to generate proper marshalling (publicType as CsStruct).IsOut = true; } } } if (publicType == null) { throw new ArgumentException("Public type cannot be null"); } paramMethod.HasPointer = hasPointer; paramMethod.Attribute = parameterAttribute; paramMethod.IsArray = hasArray; paramMethod.HasParams = hasParams; paramMethod.HasPointer = hasPointer; paramMethod.PublicType = publicType; paramMethod.MarshalType = marshalType; paramMethod.IsOptionnal = isOptional; // Force IsString to be only string (due to Buffer attribute) if (paramMethod.IsString) paramMethod.IsArray = false; method.Add(paramMethod); } }