static bool CheckBooleanMarshalling (IMarshalInfoProvider spec, MemberReference type) { // is marshalling information provided if (spec.MarshalInfo != null) return true; // using StartsWith to catch references (ref) return !type.FullName.StartsWith ("System.Boolean", StringComparison.Ordinal); }
static bool CheckBooleanMarshalling (IMarshalInfoProvider spec, TypeReference type) { // is marshalling information provided if (spec.MarshalInfo != null) return true; // using StartsWith to catch references (ref) return !(type.Namespace == "System" && type.Name.StartsWith ("Boolean", StringComparison.Ordinal)); }
public static MarshalInfo GetMarshalInfo( IMarshalInfoProvider self, ref MarshalInfo variable, ModuleDefinition module) { return Mixin.HasImage(module) ? module.Read(ref variable, self, (provider, reader) => reader.ReadMarshalInfo(provider)) : null; }
void MarkMarshalSpec (IMarshalInfoProvider spec) { if (!spec.HasMarshalInfo) return; var marshaler = spec.MarshalInfo as CustomMarshalInfo; if (marshaler == null) return; MarkType (marshaler.ManagedType); }
public static bool GetHasMarshalInfo( IMarshalInfoProvider self, ModuleDefinition module) { return Mixin.HasImage(module) && module.Read(self, (provider, reader) => reader.HasMarshalInfo(provider)); }
static Ast.Attribute ConvertMarshalInfo(IMarshalInfoProvider marshalInfoProvider, ModuleDefinition module) { MarshalInfo marshalInfo = marshalInfoProvider.MarshalInfo; Ast.Attribute attr = CreateNonCustomAttribute(typeof(MarshalAsAttribute), module); string memberName; if (marshalInfo.NativeType == NativeType.Boolean) memberName = "Bool"; else memberName = marshalInfo.NativeType.ToString(); attr.Arguments.Add(new IdentifierExpression("UnmanagedType").Member(memberName)); return attr; }
public static bool GetHasMarshalInfo( IMarshalInfoProvider self, ModuleDefinition module) { return(Mixin.HasImage(module) && module.Read(self, (provider, reader) => reader.HasMarshalInfo(provider))); }
bool CheckMarshalAsDelegate(List <TypeReference> checkedTypes, MethodDefinition method, TypeReference type, IMarshalInfoProvider provider, ref List <string>?failures) { var invokeMethod = type.Resolve().Methods.Single(v => v.Name == "Invoke"); if (!CheckMarshalAs(checkedTypes, invokeMethod, ref failures)) { AddFailure(ref failures, $"For the delegate type {type.FullName}"); return(false); } return(true); }
bool CheckMarshalAs(List <TypeReference> checkedTypes, MethodDefinition method, TypeReference type, IMarshalInfoProvider provider, ref List <string>?failures) { if (checkedTypes.Contains(type)) { return(true); } checkedTypes.Add(type); if (type.IsValueType && !type.IsPrimitive) { return(CheckValueType(checkedTypes, method, type, ref failures)); } if (IsDelegate(type)) { return(CheckMarshalAsDelegate(checkedTypes, method, type, provider, ref failures)); } if (provider.HasMarshalInfo) { return(true); } // boolean or char type without MarshalAs directive if (type.Namespace == "System") { switch (type.Name) { case "Boolean": case "Char": return(false); } } return(true); }
static bool IsComInterop(IMarshalInfoProvider marshalInfoProvider, TypeReference parameterType, LinkContext context) { // This is best effort. One can likely find ways how to get COM without triggering these alarms. // AsAny marshalling of a struct with an object-typed field would be one, for example. // This logic roughly corresponds to MarshalInfo::MarshalInfo in CoreCLR, // not trying to handle invalid cases and distinctions that are not interesting wrt // "is this COM?" question. NativeType nativeType = NativeType.None; if (marshalInfoProvider.HasMarshalInfo) { nativeType = marshalInfoProvider.MarshalInfo.NativeType; } if (nativeType == NativeType.IUnknown || nativeType == NativeType.IDispatch || nativeType == NativeType.IntF) { // This is COM by definition return(true); } if (nativeType == NativeType.None) { // Resolve will look at the element type var parameterTypeDef = context.TryResolve(parameterType); if (parameterTypeDef != null) { if (parameterTypeDef.IsTypeOf(WellKnownType.System_Array)) { // System.Array marshals as IUnknown by default return(true); } else if (parameterTypeDef.IsTypeOf(WellKnownType.System_String) || parameterTypeDef.IsTypeOf("System.Text", "StringBuilder")) { // String and StringBuilder are special cased by interop return(false); } if (parameterTypeDef.IsValueType) { // Value types don't marshal as COM return(false); } else if (parameterTypeDef.IsInterface) { // Interface types marshal as COM by default return(true); } else if (parameterTypeDef.IsMulticastDelegate()) { // Delegates are special cased by interop return(false); } else if (parameterTypeDef.IsSubclassOf("System.Runtime.InteropServices", "CriticalHandle", context)) { // Subclasses of CriticalHandle are special cased by interop return(false); } else if (parameterTypeDef.IsSubclassOf("System.Runtime.InteropServices", "SafeHandle", context)) { // Subclasses of SafeHandle are special cased by interop return(false); } else if (!parameterTypeDef.IsSequentialLayout && !parameterTypeDef.IsExplicitLayout) { // Rest of classes that don't have layout marshal as COM return(true); } } } return(false); }
static Ast.Attribute ConvertMarshalInfo(IMarshalInfoProvider marshalInfoProvider, ModuleDefinition module) { MarshalInfo marshalInfo = marshalInfoProvider.MarshalInfo; Ast.Attribute attr = CreateNonCustomAttribute(typeof(MarshalAsAttribute), module); var unmanagedType = new TypeReference("System.Runtime.InteropServices", "UnmanagedType", module, module.TypeSystem.Corlib); attr.Arguments.Add(MakePrimitive((int)marshalInfo.NativeType, unmanagedType)); return attr; }