public CsProperty(CppMethod cppCallable, string name, CsMethod getter, CsMethod setter, bool isPropertyParam = false) : base(cppCallable, name) { Getter = getter; Setter = setter; IsPropertyParam = isPropertyParam; IsPersistent = getter?.IsPersistent ?? IsPersistent; }
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); } }
/// <summary> /// Registers the native interop signature. /// </summary> /// <param name="csMethod">The cs method.</param> private void RegisterNativeInteropSignature(CsMethod csMethod) { // Tag if the method is a function var cSharpInteropCalliSignature = new InteropMethodSignature { IsFunction = (csMethod is CsFunction) }; // Handle Return Type parameter // MarshalType.Type == null, then check that it is a structure if (csMethod.ReturnType.PublicType is CsStruct || csMethod.ReturnType.PublicType is CsEnum) { // Return type and 1st parameter are implicitly a pointer to the structure to fill if (csMethod.IsReturnStructLarge) { cSharpInteropCalliSignature.ReturnType = typeof(void*); cSharpInteropCalliSignature.ParameterTypes.Add(typeof(void*)); } else { // Patch for Mono bug with structs marshalling and calli. TEMPORARY var returnQualifiedName = csMethod.ReturnType.PublicType.QualifiedName; if (returnQualifiedName == "SharpDX.Result") cSharpInteropCalliSignature.ReturnType = typeof (int); else if (returnQualifiedName == "SharpDX.PointerSize" || returnQualifiedName == "SharpDX.Direct3D9.EffectHandle") cSharpInteropCalliSignature.ReturnType = typeof(void*); else cSharpInteropCalliSignature.ReturnType = csMethod.ReturnType.PublicType.QualifiedName; } } else if (csMethod.ReturnType.MarshalType.Type != null) { Type type = csMethod.ReturnType.MarshalType.Type; //if (type == typeof(IntPtr)) // type = typeof(void*); cSharpInteropCalliSignature.ReturnType = type; } else { throw new ArgumentException(string.Format(System.Globalization.CultureInfo.InvariantCulture, "Invalid return type {0} for method {1}", csMethod.ReturnType.PublicType.QualifiedName, csMethod.CppElement)); } // Handle Parameters foreach (var param in csMethod.Parameters) { InteropType interopType; string publicName = param.PublicType.QualifiedName; // Patch for Mono bug with structs marshalling and calli. TEMPORARY if (publicName == "SharpDX.PointerSize" || param.PublicType.QualifiedName == "SharpDX.Direct3D9.EffectHandle") { interopType = typeof(void*); } else if (param.MarshalType.Type == null) { if (param.PublicType is CsStruct) { // If parameter is a struct, then a LocalInterop is needed interopType = param.PublicType.QualifiedName; cSharpInteropCalliSignature.IsLocal = true; } else { throw new ArgumentException(string.Format(System.Globalization.CultureInfo.InvariantCulture, "Invalid parameter {0} for method {1}", param.PublicType.QualifiedName, csMethod.CppElement)); } } else { Type type = param.MarshalType.Type; // Patch for Mono bug with structs marshalling and calli. TEMPORARY if (type == typeof(IntPtr)) type = typeof(void*); interopType = type; } cSharpInteropCalliSignature.ParameterTypes.Add(interopType); } var assembly = csMethod.GetParent<CsAssembly>(); cSharpInteropCalliSignature = assembly.Interop.Add(cSharpInteropCalliSignature); csMethod.Interop = cSharpInteropCalliSignature; }
/// <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); } }
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; } } }