void CreateMarshalMethodAssembly(string path) { var assembly = Assembly.LoadFile(Path.GetFullPath(path)); var baseName = Path.GetFileNameWithoutExtension(path); var assemblyName = new AssemblyName(baseName + "-JniMarshalMethods"); var fileName = assemblyName.Name + ".dll"; var destDir = string.IsNullOrEmpty(outDirectory) ? Path.GetDirectoryName(path) : outDirectory; var builder = CreateExportedMemberBuilder(); var matchType = typeNameRegexes.Count > 0; if (Verbose) { ColorWriteLine($"Preparing marshal method assembly '{assemblyName}'", ConsoleColor.Cyan); } var da = AppDomain.CurrentDomain.DefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.Save, destDir); var dm = da.DefineDynamicModule("<default>", fileName); var ad = resolver.GetAssembly(path); PrepareTypeMap(ad.MainModule); Type[] types = null; try { types = assembly.GetTypes(); } catch (ReflectionTypeLoadException e) { types = e.Types; foreach (var le in e.LoaderExceptions) { Warning($"Type Load exception{Environment.NewLine}{le}"); } } foreach (var systemType in types) { if (systemType == null) { continue; } var type = systemType.GetTypeInfo(); if (matchType) { var matched = false; foreach (var r in typeNameRegexes) { matched |= r.IsMatch(type.FullName); } if (!matched) { continue; } } if (type.IsInterface || type.IsGenericType || type.IsGenericTypeDefinition) { continue; } var td = FindType(type); if (td == null) { if (Verbose) { Warning($"Unable to find cecil's TypeDefinition of type {type}"); } continue; } if (!td.ImplementsInterface("Java.Interop.IJavaPeerable", cache)) { continue; } var existingMarshalMethodsType = td.GetNestedType(TypeMover.NestedName); if (existingMarshalMethodsType != null && !forceRegeneration) { Warning($"Marshal methods type '{existingMarshalMethodsType.GetAssemblyQualifiedName (cache)}' already exists. Skipped generation of marshal methods in assembly '{assemblyName}'. Use -f to force regeneration when desired."); return; } if (Verbose) { ColorWriteLine($"Processing {type} type", ConsoleColor.Yellow); } var registrationElements = new List <Expression> (); var targetType = Expression.Variable(typeof(Type), "targetType"); TypeBuilder dt = null; var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; var methods = type.GetMethods(flags); Array.Sort(methods, new MethodsComparer(type, td)); addedMethods.Clear(); foreach (var method in methods) { // TODO: Constructors var export = method.GetCustomAttribute <JavaCallableAttribute> (); string signature = null; string name = null; string methodName = method.Name; if (export == null) { if (method.IsGenericMethod || method.ContainsGenericParameters || method.IsGenericMethodDefinition || method.ReturnType.IsGenericType) { continue; } if (method.DeclaringType != type) { continue; } var md = td.GetMethodDefinition(method); if (md == null) { if (Verbose) { Warning($"Unable to find cecil's MethodDefinition of method {method}"); } continue; } if (!md.NeedsMarshalMethod(resolver, cache, method, ref name, ref methodName, ref signature)) { continue; } } #if !_ALL_THE_ARGUMENTS if (method.GetParameters().Length > 14) { Warning($"Methods taking more than 14 parameters is not supported."); continue; } #endif // !_ALL_THE_ARGUMENTS if (dt == null) { dt = GetTypeBuilder(dm, type); } if (addedMethods.Contains(methodName)) { continue; } if (Verbose) { Console.Write("Adding marshal method for "); ColorWriteLine($"{method}", ConsoleColor.Green); } var mb = dt.DefineMethod( methodName, System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Static); var lambda = builder.CreateMarshalToManagedExpression(method); lambda.CompileToMethod(mb); if (export != null) { name = export.Name; signature = export.Signature; } if (signature == null) { signature = builder.GetJniMethodSignature(method); } registrationElements.Add(CreateRegistration(name, signature, lambda, targetType, methodName)); addedMethods.Add(methodName); } if (dt != null) { AddRegisterNativeMembers(dt, targetType, registrationElements); } } foreach (var tb in definedTypes) { tb.Value.CreateType(); } da.Save(fileName); if (Verbose) { ColorWriteLine($"Marshal method assembly '{assemblyName}' created", ConsoleColor.Cyan); } resolver.SearchDirectories.Add(destDir); var dstAssembly = resolver.GetAssembly(fileName); if (!string.IsNullOrEmpty(outDirectory)) { path = Path.Combine(outDirectory, Path.GetFileName(path)); } var mover = new TypeMover(dstAssembly, ad, path, definedTypes, resolver, cache); mover.Move(); if (!keepTemporary) { FilesToDelete.Add(dstAssembly.MainModule.FileName); } }
void CreateMarshalMethodAssembly(string path) { var assembly = Assembly.LoadFile(path); var baseName = Path.GetFileNameWithoutExtension(path); var assemblyName = new AssemblyName(baseName + "-JniMarshalMethods"); var destPath = assemblyName.Name + ".dll"; var builder = CreateExportedMemberBuilder(); var matchType = typeNameRegexes.Count > 0; if (Verbose) { ColorWriteLine($"Preparing marshal method assembly '{assemblyName}'", ConsoleColor.Cyan); } var da = AppDomain.CurrentDomain.DefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.Save, Path.GetDirectoryName(path)); var dm = da.DefineDynamicModule("<default>", destPath); var ad = resolver.GetAssembly(path); foreach (var type in assembly.DefinedTypes) { if (matchType) { var matched = false; foreach (var r in typeNameRegexes) { matched |= r.IsMatch(type.FullName); } if (!matched) { continue; } } if (type.IsGenericType || type.IsGenericTypeDefinition) { continue; } var td = ad.MainModule.FindType(type); if (td == null) { if (Verbose) { Warning($"Unable to find cecil's TypeDefinition of type {type}"); } continue; } if (!td.ImplementsInterface("Java.Interop.IJavaPeerable")) { continue; } var existingMarshalMethodsType = td.GetNestedType(TypeMover.NestedName); if (existingMarshalMethodsType != null && !forceRegeneration) { Warning($"Marshal methods type '{existingMarshalMethodsType.GetAssemblyQualifiedName ()}' already exists. Skipped generation of marshal methods. Use -f to force regeneration when desired."); continue; } var registrationElements = new List <Expression> (); var targetType = Expression.Variable(typeof(Type), "targetType"); TypeBuilder dt = null; var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; foreach (var method in type.GetMethods(flags)) { // TODO: Constructors var export = method.GetCustomAttribute <JavaCallableAttribute> (); string signature = null; string name = null; string methodName = method.Name; if (export == null) { if (method.IsGenericMethod || method.ContainsGenericParameters || method.IsGenericMethodDefinition || method.ReturnType.IsGenericType) { continue; } if (method.DeclaringType != type) { continue; } var md = td.GetMethodDefinition(method); if (md == null) { if (Verbose) { Warning($"Unable to find cecil's MethodDefinition of method {method}"); } continue; } if (!md.NeedsMarshalMethod(resolver, method, ref name, ref methodName, ref signature)) { continue; } } if (dt == null) { dt = GetTypeBuilder(dm, type); } if (Verbose) { Console.Write("Adding marshal method for "); ColorWriteLine($"{method}", ConsoleColor.Green); } var mb = dt.DefineMethod( methodName, System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Static); var lambda = builder.CreateMarshalToManagedExpression(method); lambda.CompileToMethod(mb); if (export != null) { name = export.Name; signature = export.Signature; } if (signature == null) { signature = builder.GetJniMethodSignature(method); } registrationElements.Add(CreateRegistration(name, signature, lambda, targetType, methodName)); } if (dt != null) { AddRegisterNativeMembers(dt, targetType, registrationElements); } } foreach (var tb in definedTypes) { tb.Value.CreateType(); } da.Save(destPath); if (Verbose) { ColorWriteLine($"Marshal method assembly '{assemblyName}' created", ConsoleColor.Cyan); } var dstAssembly = resolver.GetAssembly(destPath); var mover = new TypeMover(dstAssembly, ad, definedTypes, resolver); mover.Move(); if (!keepTemporary) { FilesToDelete.Add(dstAssembly.MainModule.FileName); } definedTypes.Clear(); }