Exemple #1
0
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;
}
Exemple #2
0
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;
	}