Error GodotSharpExport::_get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Map<String, String> &r_dependencies) { MonoImage *image = p_assembly->get_image(); for (int i = 0; i < mono_image_get_table_rows(image, MONO_TABLE_ASSEMBLYREF); i++) { MonoAssemblyName *ref_aname = aname_prealloc; mono_assembly_get_assemblyref(image, i, ref_aname); String ref_name = mono_assembly_name_get_name(ref_aname); if (r_dependencies.find(ref_name)) continue; GDMonoAssembly *ref_assembly = NULL; String path; bool has_extension = ref_name.ends_with(".dll") || ref_name.ends_with(".exe"); for (int j = 0; j < p_search_dirs.size(); j++) { const String &search_dir = p_search_dirs[j]; if (has_extension) { path = search_dir.plus_file(ref_name); if (FileAccess::exists(path)) { GDMono::get_singleton()->load_assembly_from(ref_name.get_basename(), path, &ref_assembly, true); if (ref_assembly != NULL) break; } } else { path = search_dir.plus_file(ref_name + ".dll"); if (FileAccess::exists(path)) { GDMono::get_singleton()->load_assembly_from(ref_name, path, &ref_assembly, true); if (ref_assembly != NULL) break; } path = search_dir.plus_file(ref_name + ".exe"); if (FileAccess::exists(path)) { GDMono::get_singleton()->load_assembly_from(ref_name, path, &ref_assembly, true); if (ref_assembly != NULL) break; } } } if (!ref_assembly) { ERR_EXPLAIN("Cannot load assembly (refonly): " + ref_name); ERR_FAIL_V(ERR_CANT_RESOLVE); } r_dependencies.insert(ref_name, ref_assembly->get_path()); Error err = _get_assembly_dependencies(ref_assembly, p_search_dirs, r_dependencies); if (err != OK) return err; } return OK; }
MonoAssembly *gdmono_MonoAssemblyPreLoad(MonoAssemblyName *aname, char **assemblies_path, void *user_data) { (void)user_data; // UNUSED MonoAssembly *assembly_loaded = mono_assembly_loaded(aname); if (assembly_loaded) // Already loaded return assembly_loaded; static Vector<String> search_dirs; if (search_dirs.empty()) { search_dirs.push_back(GodotSharpDirs::get_res_temp_assemblies_dir()); search_dirs.push_back(GodotSharpDirs::get_res_assemblies_dir()); search_dirs.push_back(OS::get_singleton()->get_resource_dir()); search_dirs.push_back(OS::get_singleton()->get_executable_path().get_base_dir()); const char *rootdir = mono_assembly_getrootdir(); if (rootdir) { search_dirs.push_back(String(rootdir).plus_file("mono").plus_file("4.5")); } while (assemblies_path) { if (*assemblies_path) search_dirs.push_back(*assemblies_path); ++assemblies_path; } } String name = mono_assembly_name_get_name(aname); bool has_extension = name.ends_with(".dll") || name.ends_with(".exe"); String path; for (int i = 0; i < search_dirs.size(); i++) { const String &search_dir = search_dirs[i]; if (has_extension) { path = search_dir.plus_file(name); if (FileAccess::exists(path)) return gdmono_load_assembly_from(name.get_basename(), path); } else { path = search_dir.plus_file(name + ".dll"); if (FileAccess::exists(path)) return gdmono_load_assembly_from(name, path); path = search_dir.plus_file(name + ".exe"); if (FileAccess::exists(path)) return gdmono_load_assembly_from(name, path); } } return NULL; }
MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_data) { (void)user_data; // UNUSED String name = mono_assembly_name_get_name(aname); bool has_extension = name.ends_with(".dll") || name.ends_with(".exe"); if (no_search) return NULL; GDMonoAssembly **loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name); if (loaded_asm) return (*loaded_asm)->get_assembly(); no_search = true; // Avoid the recursion madness String path; MonoAssembly *res = NULL; for (int i = 0; i < search_dirs.size(); i++) { const String &search_dir = search_dirs[i]; if (has_extension) { path = search_dir.plus_file(name); if (FileAccess::exists(path)) { res = _load_assembly_from(name.get_basename(), path); break; } } else { path = search_dir.plus_file(name + ".dll"); if (FileAccess::exists(path)) { res = _load_assembly_from(name, path); break; } path = search_dir.plus_file(name + ".exe"); if (FileAccess::exists(path)) { res = _load_assembly_from(name, path); break; } } } no_search = false; return res; }