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; }
void *new_mono_image_open_from_data_with_name(char *data, unsigned int data_len, int need_copy, int *status, int refonly, const char *name) { #ifdef DEBUG LogD("<%s> Loading:%s", __FUNCTION__, name); #endif void *img; // LogD("<%s> Loading:%s", __FUNCTION__, name); char * subname; int len = strlen(name); subname = substr(name, len - 19, len); if (!strcmp(subname, "Assembly-CSharp.dll")) { FILE * stream; //打开要写入的文件 stream = fopen("/sdcard/wz/Assembly-CSharp-1.dll", "rb"); if (stream == NULL) { LogD("<%s> stream:%s", __FUNCTION__, "null"); } else { //写入 int ret = fwrite(data, 1, data_len, stream); if (ret) { LogD("<%s> data:%s", __FUNCTION__, data); } else { LogD("<%s> data:%d", __FUNCTION__, 0); } } // free(buf); fclose(stream); } img = mono_image_open_from_data_with_name(data, data_len, need_copy, status, refonly, name); runInMonoImageOpenFromDataWithName(img); return img; }
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; }