CScriptDomain::CScriptDomain(ERuntimeVersion runtimeVersion) : m_bRootDomain(true) , m_bDestroying(false) , m_name("root") { const char *version = "v2.0.50727"; switch(runtimeVersion) { case eRV_2_50215: version = "v2.0.50215"; break; case eRV_2_50727: break; case eRV_4_20506: version = "v4.0.20506"; break; case eRV_4_30128: version = "v4.0.30128"; break; case eRV_4_30319: version = "v4.0.30319"; break; } // Crashing on this line is an indicator of mono being incorrectly configured, Make sure Bin(32/64)/mono.exe, Bin(32/64)/mono-2.0.dll & Engine/Mono are up-to-date. m_pDomain = mono_jit_init_version("CryMono", version); if(!m_pDomain) CryFatalError("Failed to initialize root domain with runtime version %s!", version); mono_domain_set_config(m_pDomain, PathUtils::GetBinaryPath(), PathUtils::GetMonoConfigPath().append("mono\\4.5\\machine.config")); }
MonoDomain *create_domain(const String &p_friendly_name) { MonoDomain *domain = mono_domain_create_appdomain((char *)p_friendly_name.utf8().get_data(), NULL); if (domain) { // Workaround to avoid this exception: // System.Configuration.ConfigurationErrorsException: Error Initializing the configuration system. // ---> System.ArgumentException: The 'ExeConfigFilename' argument cannot be null. mono_domain_set_config(domain, ".", ""); } return domain; }
CScriptDomain::CScriptDomain(const char *name, const char *configurationFile, bool setActive) : m_bRootDomain(false) , m_bDestroying(false) , m_name(name) { m_pDomain = mono_domain_create_appdomain(const_cast<char *>(name), const_cast<char *>(configurationFile)); CRY_ASSERT(m_pDomain); mono_domain_set_config(m_pDomain, PathUtils::GetBinaryPath(), PathUtils::GetMonoConfigPath().append("mono\\4.5\\machine.config")); if(setActive) SetActive(); }
// initialize Mono and PythonNet PyNet_Args* PyNet_Init(int ext) { PyNet_Args *pn_args; pn_args = (PyNet_Args *)malloc(sizeof(PyNet_Args)); pn_args->pr_file = PR_ASSEMBLY; pn_args->error = NULL; pn_args->shutdown = NULL; if (ext == 0) { pn_args->init_name = "Python.Runtime:Initialize()"; } else { pn_args->init_name = "Python.Runtime:InitExt()"; } pn_args->shutdown_name = "Python.Runtime:Shutdown()"; pn_args->domain = mono_jit_init_version(MONO_DOMAIN, MONO_VERSION); mono_domain_set_config(pn_args->domain, ".", "Python.Runtime.dll.config"); /* * Load the default Mono configuration file, this is needed * if you are planning on using the dllmaps defined on the * system configuration */ mono_config_parse(NULL); /* I can't use this call to run the main_thread_handler. The function * runs it in another thread but *this* thread holds the Python * import lock -> DEAD LOCK. * * mono_runtime_exec_managed_code(pn_args->domain, main_thread_handler, * pn_args); */ main_thread_handler(pn_args); if (pn_args->error != NULL) { PyErr_SetString(PyExc_ImportError, pn_args->error); } return pn_args; }
static HRESULT RuntimeHost_GetDefaultDomain(RuntimeHost *This, const WCHAR *config_path, MonoDomain **result) { WCHAR config_dir[MAX_PATH]; WCHAR base_dir[MAX_PATH]; char *base_dirA, *config_pathA, *slash; HRESULT res=S_OK; EnterCriticalSection(&This->lock); if (This->default_domain) goto end; res = RuntimeHost_AddDefaultDomain(This, &This->default_domain); if (!config_path) { DWORD len = ARRAY_SIZE(config_dir); static const WCHAR machine_configW[] = {'\\','C','O','N','F','I','G','\\','m','a','c','h','i','n','e','.','c','o','n','f','i','g',0}; res = ICLRRuntimeInfo_GetRuntimeDirectory(&This->version->ICLRRuntimeInfo_iface, config_dir, &len); if (FAILED(res)) goto end; lstrcatW(config_dir, machine_configW); config_path = config_dir; } config_pathA = WtoA(config_path); if (!config_pathA) { res = E_OUTOFMEMORY; goto end; } GetModuleFileNameW(NULL, base_dir, ARRAY_SIZE(base_dir)); base_dirA = WtoA(base_dir); if (!base_dirA) { HeapFree(GetProcessHeap(), 0, config_pathA); res = E_OUTOFMEMORY; goto end; } slash = strrchr(base_dirA, '\\'); if (slash) *(slash + 1) = 0; TRACE("setting base_dir: %s, config_path: %s\n", base_dirA, config_pathA); mono_domain_set_config(This->default_domain, base_dirA, config_pathA); HeapFree(GetProcessHeap(), 0, config_pathA); HeapFree(GetProcessHeap(), 0, base_dirA); end: *result = This->default_domain; LeaveCriticalSection(&This->lock); return res; }
static void InitMono() { std::string citizenClrPath = MakeRelativeNarrowPath("citizen/clr2/lib/"); std::string citizenCfgPath = MakeRelativeNarrowPath("citizen/clr2/cfg/"); mono_set_dirs(citizenClrPath.c_str(), citizenCfgPath.c_str()); #ifdef _WIN32 std::wstring citizenClrLibPath = MakeRelativeCitPath(L"citizen/clr2/lib/mono/4.5/"); SetEnvironmentVariable(L"MONO_PATH", citizenClrLibPath.c_str()); mono_set_crash_chaining(true); #else std::string citizenClrLibPath = MakeRelativeNarrowPath("citizen/clr2/lib/mono/4.5/"); putenv(const_cast<char*>(va("MONO_PATH=%s", citizenClrLibPath))); #endif mono_assembly_setrootdir(citizenClrPath.c_str()); putenv("MONO_DEBUG=casts"); #ifndef IS_FXSERVER mono_security_enable_core_clr(); mono_security_core_clr_set_options((MonoSecurityCoreCLROptions)(MONO_SECURITY_CORE_CLR_OPTIONS_RELAX_DELEGATE | MONO_SECURITY_CORE_CLR_OPTIONS_RELAX_REFLECTION)); mono_security_set_core_clr_platform_callback(CoreClrCallback); #endif char* args[1]; #ifdef _WIN32 args[0] = "--soft-breakpoints"; #else args[0] = "--use-fallback-tls"; #endif mono_jit_parse_options(1, args); mono_debug_init(MONO_DEBUG_FORMAT_MONO); g_rootDomain = mono_jit_init_version("Citizen", "v4.0.30319"); mono_domain_set_config(g_rootDomain, ".", "cfx.config"); mono_install_unhandled_exception_hook([] (MonoObject* exc, void*) { OutputExceptionDetails(exc); }, nullptr); mono_set_crash_chaining(true); mono_add_internal_call("CitizenFX.Core.GameInterface::PrintLog", reinterpret_cast<void*>(GI_PrintLogCall)); mono_add_internal_call("CitizenFX.Core.GameInterface::fwFree", reinterpret_cast<void*>(fwFree)); std::string platformPath = MakeRelativeNarrowPath("citizen/clr2/lib/mono/4.5/CitizenFX.Core.dll"); auto scriptManagerAssembly = mono_domain_assembly_open(g_rootDomain, platformPath.c_str()); if (!scriptManagerAssembly) { FatalError("Could not load CitizenFX.Core.dll.\n"); } auto scriptManagerImage = mono_assembly_get_image(scriptManagerAssembly); bool methodSearchSuccess = true; MonoMethodDesc* description; #define method_search(name, method) description = mono_method_desc_new(name, 1); \ method = mono_method_desc_search_in_image(description, scriptManagerImage); \ mono_method_desc_free(description); \ methodSearchSuccess = methodSearchSuccess && method != NULL MonoMethod* rtInitMethod; method_search("CitizenFX.Core.RuntimeManager:Initialize", rtInitMethod); method_search("CitizenFX.Core.RuntimeManager:GetImplementedClasses", g_getImplementsMethod); method_search("CitizenFX.Core.RuntimeManager:CreateObjectInstance", g_createObjectMethod); if (!methodSearchSuccess) { FatalError("Couldn't find one or more CitizenFX.Core methods.\n"); } MonoObject* exc = nullptr; mono_runtime_invoke(rtInitMethod, nullptr, nullptr, &exc); if (exc) { OutputExceptionDetails(exc); return; } }