//============================================================ // <T>析构脚本工作器。</T> // // @return 处理结果 //============================================================ TResult FMonoLibrary::Open(){ TResult resultCd = FScriptLibrary::Open(); // 打开资源 FAssetStream* pStream = RAssetManager::Instance().OpenAssetStreamFormat(_name); MO_ERROR_CHECK(pStream, return NULL, "Open template stream failure. (name=%s)", (TCharC*)_name); // 加载映像 MonoImageOpenStatus statusCd = MONO_IMAGE_IMAGE_INVALID; _pMonoImage = mono_image_open_from_data_full((TChar*)pStream->MemoryC(), pStream->Length(), true, &statusCd, false); MO_FATAL_CHECK(_pMonoImage, return EFailure, "Open assembly image failure. (name=%s)", (TCharC*)_name); if(statusCd != MONO_IMAGE_OK){ MO_FATAL("Open assembly image failure. (file_name=%s)", _name); return EFailure; } // 加载装配数据 MonoImageOpenStatus assemblyStatusCd = MONO_IMAGE_IMAGE_INVALID; MonoAssembly* pAssembly = mono_assembly_load_from_full(_pMonoImage, _name, &assemblyStatusCd, false); MO_FATAL_CHECK(pAssembly, return EFailure, "Load assembly failure. (name=%s)", (TCharC*)_name); if(mono_assembly_get_image(pAssembly) != _pMonoImage){ MO_FATAL("Check mono image failure. (image=0x%08X)", _pMonoImage); return EFailure; } // 释放资源 RAssetManager::Instance().CloseAssetStream(pStream); return resultCd; }
/** * Starts the mono runtime, and loads the encapsulated assembly, unless * it's already been loaded. */ void sp_ensure_runtime() { /* Check that the runtime hasn't already been started. */ if (runtime_started) { return; } /* Initialise the JIT. */ m_domain = mono_jit_init_version(__assembly_info.name, __assembly_info.version); if (!m_domain) { printf("error: unable to create mono domain\n"); _exit(0); } /* Open the assembly image, from the data inside the object * file. This data is accessed via the special symbols created * when the PE is linked in as a binary object. */ m_image = mono_image_open_from_data(&_binary_test_dll_start, &_binary_test_dll_end - &_binary_test_dll_start, 0, NULL); if (!m_image) { printf("error: unable to open assembly image\n"); _exit(0); } /* Now, load the assembly. */ m_assembly = mono_assembly_load_from_full(m_image, __assembly_info.name, NULL, 0); if (!m_assembly) { printf("error: unable to load assembly\n"); _exit(0); } /* Mark the runtime as started, just in case we neglected to * rewrite some function stubs. */ runtime_started = 1; }
Error GDMonoAssembly::load(MonoDomain *p_domain) { ERR_FAIL_COND_V(loaded, ERR_FILE_ALREADY_IN_USE); uint64_t last_modified_time = FileAccess::get_modified_time(path); Vector<uint8_t> data = FileAccess::get_file_as_array(path); ERR_FAIL_COND_V(data.empty(), ERR_FILE_CANT_READ); String image_filename(path); MonoImageOpenStatus status; image = mono_image_open_from_data_with_name( (char *)&data[0], data.size(), true, &status, false, image_filename.utf8().get_data()); ERR_FAIL_COND_V(status != MONO_IMAGE_OK || image == NULL, ERR_FILE_CANT_OPEN); #ifdef DEBUG_ENABLED String pdb_path(path + ".pdb"); if (!FileAccess::exists(pdb_path)) { pdb_path = path.get_basename() + ".pdb"; // without .dll if (!FileAccess::exists(pdb_path)) goto no_pdb; } pdb_data.clear(); pdb_data = FileAccess::get_file_as_array(pdb_path); mono_debug_open_image_from_memory(image, &pdb_data[0], pdb_data.size()); no_pdb: #endif assembly = mono_assembly_load_from_full(image, image_filename.utf8().get_data(), &status, false); ERR_FAIL_COND_V(status != MONO_IMAGE_OK || assembly == NULL, ERR_FILE_CANT_OPEN); if (p_domain && mono_image_get_entry_point(image)) { // TODO should this be removed? do we want to call main? what other effects does this have? mono_jit_exec(p_domain, assembly, 0, NULL); } loaded = true; modified_time = last_modified_time; return OK; }
//##################################################################### // Function loadAssembly //##################################################################### bool MonoSystem::loadMemoryAssembly(char* membuf, unsigned int len) const { MonoAssembly *ass; MonoImageOpenStatus status = MONO_IMAGE_OK; MonoImage *image = mono_image_open_from_data_full(membuf, len, TRUE, &status, false); if (!image) { // bad image format printf("Error loading image from memory: %d\n", status); return false; } ass = mono_assembly_load_from_full (image, "", &status, false); if (!ass) { printf("Error loading assembly from memory: %d\n", status); // FIXME real error reporting // bad image format? mono_image_close (image); return false; } return true; }
bool Application::StartMonoAndLoadAssemblies() { // shutdown the child domain StopMono(); // create a new child domain if (!StartMono()) { mono_environment_exitcode_set(-1); return true; } std::string dll = "EmbedThings.dll"; std::string filename = File::BuildRootedPath(assemblyDir, dll); size_t length; // read our entry point assembly char* data = File::Read(filename.c_str(), &length); printf_console("Loading %s into Domain\n", dll.c_str()); MonoImageOpenStatus status; // open the assembly from the data we read, so we never lock files auto image = mono_image_open_from_data_with_name(data, length, true /* copy data */, &status, false /* ref only */, filename.c_str()); if (status != MONO_IMAGE_OK || image == nullptr) { printf_console("Failed loading assembly %s\n", dll); return true; } // load the assembly auto assembly = mono_assembly_load_from_full(image, filename.c_str(), &status, false); if (status != MONO_IMAGE_OK || assembly == nullptr) { mono_image_close(image); printf_console("Failed loading assembly %s\n", dll); return true; } // save the image for lookups later and for cleaning up images.push_back(image); if (!assembly) { printf_console("Couldn't find assembly %s\n", filename.c_str()); return true; } // locate the class we want to load MonoClass* klass = mono_class_from_name(image, "EmbedThings", "EntryPoint"); if (klass == nullptr) { printf_console("Failed loading class %s\n", "EmbedThings.EntryPoint"); return true; } // create the class (doesn't run constructors) MonoObject* obj = mono_object_new(mono_domain_get(), klass); if (obj == nullptr) { printf_console("Failed loading class instance %s\n", "EmbedThings.EntryPoint"); return true; } // initialize the class instance (runs default constructors) mono_runtime_object_init(obj); if (obj == nullptr) { printf_console("Failed initializing class instance %s\n", "EmbedThings.EntryPoint"); return true; } // save the class instance for lookups later instances.push_back(obj); // find the Run() method auto method = find_method(klass, "Run"); MonoObject *result, *exception; // call the Run method. This will block until the managed code decides to exit result = mono_runtime_invoke(method, obj, NULL, NULL); int val = *(int*)mono_object_unbox(result); // if the managed code returns with 0, it wants to exit completely if (val == 0) { return true; } return false; }
void MonoAssembly::load(MonoDomain* domain) { if (mIsLoaded) unload(); // Load assembly from memory because mono_domain_assembly_open keeps a lock on the file SPtr<DataStream> assemblyStream = FileSystem::openFile(mPath, true); if (assemblyStream == nullptr) { LOGERR("Cannot load assembly at path \"" + toString(mPath) + "\" because the file doesn't exist"); return; } UINT32 assemblySize = (UINT32)assemblyStream->size(); char* assemblyData = (char*)bs_stack_alloc(assemblySize); assemblyStream->read(assemblyData, assemblySize); String imageName = Path(mPath).getFilename(); MonoImageOpenStatus status = MONO_IMAGE_OK; MonoImage* image = mono_image_open_from_data_with_name(assemblyData, assemblySize, true, &status, false, imageName.c_str()); bs_stack_free(assemblyData); if (status != MONO_IMAGE_OK || image == nullptr) { LOGERR("Failed loading image data for assembly \"" + toString(mPath) + "\""); return; } // Load MDB file #if BS_DEBUG_MODE Path mdbPath = mPath + L".mdb"; if (FileSystem::exists(mdbPath)) { SPtr<DataStream> mdbStream = FileSystem::openFile(mdbPath, true); if (mdbStream != nullptr) { UINT32 mdbSize = (UINT32)mdbStream->size(); mDebugData = (UINT8*)bs_alloc(mdbSize); mdbStream->read(mDebugData, mdbSize); mono_debug_open_image_from_memory(image, mDebugData, mdbSize); } } #endif mMonoAssembly = mono_assembly_load_from_full(image, imageName.c_str(), &status, false); if (status != MONO_IMAGE_OK || mMonoAssembly == nullptr) { LOGERR("Failed loading assembly \"" + toString(mPath) + "\""); return; } mMonoImage = image; if(mMonoImage == nullptr) { BS_EXCEPT(InvalidParametersException, "Cannot get script assembly image."); } mIsLoaded = true; mIsDependency = false; }
void *new_mono_assembly_load_from_full(void *image, const char *fname, int *status, int refonly) { return mono_assembly_load_from_full(image, fname, status, refonly); }