private void GenerateType(TypeDefinition type) { // Generate nested types recursively foreach (var nestedType in type.NestedTypes) { GenerateType(nestedType); } // Delegate tagged with UnmanagedFunctionPointerAttribute should have delegate wrapper generated for them (even if not used in any PInvoke method directly) if (type.HasCustomAttributes && type.CustomAttributes.Any(x => x.AttributeType.FullName == typeof(UnmanagedFunctionPointerAttribute).FullName)) { DelegateMarshaller.GetOrCreateGenerateDelegateWrapper(assemblyDefinition, type); } foreach (var method in type.Methods.ToArray()) { if (method.HasPInvokeInfo) { Process(method); } } }
/// <summary> /// Finds the marshaller for given <see cref="TypeReference"/> and <see cref="MarshalInfo"/>. /// </summary> /// <param name="type">The type.</param> /// <param name="marshalInfo">The marshal information.</param> /// <returns></returns> /// <exception cref="System.NotImplementedException"> /// </exception> public static Marshaller FindMarshallerForType(TypeReference type, MarshalInfo marshalInfo) { // First, check the cache // TODO: Take marshalInfo into account Marshaller marshaller; if (marshallers.TryGetValue(type, out marshaller)) { return(marshaller); } if (marshalInfo != null) { switch (marshalInfo.NativeType) { case NativeType.IUnknown: case NativeType.IntF: // TODO: Implement a real marshaller for that case return(new BlittableMarshaller()); } } switch (type.MetadataType) { case MetadataType.Object: case MetadataType.ValueType: case MetadataType.Class: { // Various types with specific marshallers if (type.FullName == typeof(HandleRef).FullName) { marshaller = new HandleRefMarshaller(); break; } if (type.FullName == typeof(StringBuilder).FullName) { marshaller = new StringBuilderMarshaller(); break; } if (type.FullName == typeof(string).FullName) { marshaller = new StringMarshaller(marshalInfo); break; } var typeDefinition = type.Resolve(); // Check if type is a delegate if (typeDefinition.BaseType != null && typeDefinition.BaseType.FullName == typeof(MulticastDelegate).FullName) { marshaller = new DelegateMarshaller(); break; } // Check if type is a reference type if (!typeDefinition.IsValueType) { return(new BlittableMarshaller()); } if (typeDefinition.IsEnum) { return(new BlittableMarshaller()); } // Check if type is blittable if (IsBlittable(type, marshalInfo)) { marshaller = new BlittableMarshaller(); break; } marshaller = new StructMarshaller(type); break; } case MetadataType.Boolean: if (marshalInfo != null) { // I1/U1 boolean don't need any marshalling if (marshalInfo.NativeType == NativeType.I1 || marshalInfo.NativeType == NativeType.U1) { marshaller = new BlittableMarshaller(); } else { throw new NotImplementedException(); } } else { // Default case: 4-byte integer marshaller = new BooleanMarshaller(); } break; case MetadataType.SByte: case MetadataType.Byte: case MetadataType.Int16: case MetadataType.UInt16: case MetadataType.Int32: case MetadataType.UInt32: case MetadataType.Int64: case MetadataType.UInt64: case MetadataType.Single: case MetadataType.Double: case MetadataType.IntPtr: case MetadataType.UIntPtr: case MetadataType.Pointer: case MetadataType.Char: marshaller = new BlittableMarshaller(); break; case MetadataType.String: marshaller = new StringMarshaller(marshalInfo); break; case MetadataType.Array: { var elementType = ((ArrayType)type).ElementType; if (IsBlittable(elementType, marshalInfo)) { marshaller = new BlittableArrayMarshaller(); break; } marshaller = new ArrayMarshaller(FindMarshallerForType(elementType, marshalInfo)); break; } default: throw new NotImplementedException(string.Format("Marshaller for type {0}", type)); } marshallers[type] = marshaller; return(marshaller); }
/// <summary> /// Finds the marshaller for given <see cref="TypeReference"/> and <see cref="MarshalInfo"/>. /// </summary> /// <param name="type">The type.</param> /// <param name="marshalInfo">The marshal information.</param> /// <returns></returns> /// <exception cref="System.NotImplementedException"> /// </exception> public static Marshaller FindMarshallerForType(TypeReference type, MarshalInfo marshalInfo) { // First, check the cache // TODO: Take marshalInfo into account Marshaller marshaller; if (marshallers.TryGetValue(type, out marshaller)) return marshaller; if (marshalInfo != null) { switch (marshalInfo.NativeType) { case NativeType.IUnknown: case NativeType.IntF: // TODO: Implement a real marshaller for that case return new BlittableMarshaller(); } } switch (type.MetadataType) { case MetadataType.Object: case MetadataType.ValueType: case MetadataType.Class: { // Various types with specific marshallers if (type.FullName == typeof(HandleRef).FullName) { marshaller = new HandleRefMarshaller(); break; } if (type.FullName == typeof(StringBuilder).FullName) { marshaller = new StringBuilderMarshaller(); break; } if (type.FullName == typeof(string).FullName) { marshaller = new StringMarshaller(marshalInfo); break; } var typeDefinition = type.Resolve(); // Check if type is a delegate if (typeDefinition.BaseType != null && typeDefinition.BaseType.FullName == typeof(MulticastDelegate).FullName) { marshaller = new DelegateMarshaller(); break; } // Check if type is a reference type if (!typeDefinition.IsValueType) return new BlittableMarshaller(); if (typeDefinition.IsEnum) return new BlittableMarshaller(); // Check if type is blittable if (IsBlittable(type, marshalInfo)) { marshaller = new BlittableMarshaller(); break; } marshaller = new StructMarshaller(type); break; } case MetadataType.Boolean: if (marshalInfo != null) { // I1/U1 boolean don't need any marshalling if (marshalInfo.NativeType == NativeType.I1 || marshalInfo.NativeType == NativeType.U1) marshaller = new BlittableMarshaller(); else throw new NotImplementedException(); } else { // Default case: 4-byte integer marshaller = new BooleanMarshaller(); } break; case MetadataType.SByte: case MetadataType.Byte: case MetadataType.Int16: case MetadataType.UInt16: case MetadataType.Int32: case MetadataType.UInt32: case MetadataType.Int64: case MetadataType.UInt64: case MetadataType.Single: case MetadataType.Double: case MetadataType.IntPtr: case MetadataType.UIntPtr: case MetadataType.Pointer: case MetadataType.Char: marshaller = new BlittableMarshaller(); break; case MetadataType.String: marshaller = new StringMarshaller(marshalInfo); break; case MetadataType.Array: { var elementType = ((ArrayType)type).ElementType; if (IsBlittable(elementType, marshalInfo)) { marshaller = new BlittableArrayMarshaller(); break; } marshaller = new ArrayMarshaller(FindMarshallerForType(elementType, marshalInfo)); break; } default: throw new NotImplementedException(string.Format("Marshaller for type {0}", type)); } marshallers[type] = marshaller; return marshaller; }