Example #1
0
//============================================================
// <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;
}
Example #2
0
/**
 * 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;
}
Example #3
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;
}
Example #4
0
//#####################################################################
// 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;
}
Example #5
0
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;
	}
Example #7
0
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);
}