Skip to content

Interop Classes

RoqueDeicide edited this page Jan 1, 2015 · 1 revision

Interop classes are types that implement IMonoInterop interface. Their primary purpose is making registration of internal calls easier.

Methods that are invoked using the internal call mechanism should be either global or static functions. Their signature should closely match the signature of corresponding C# function.

C++ code of one of existing interops:

#include "IMonoInterface.h"
//! Broadcasts CryCIL events to listeners from managed code.
struct InitializationInterop : public IDefaultMonoInterop
{
	static class MonoInterface *monoEnv;	//!< For static functions.
	virtual const char *GetName();

	virtual void OnRunTimeInitialized();

	virtual void SetInterface(IMonoInterface *handle);

	static void OnCompilationStartingBind();
	static void OnCompilationCompleteBind(bool success);
	static mono::Array GetSubscribedStagesBind();
	static void OnInitializationStageBind(int stageIndex);
};

#include "RunTime/MonoInterface.h"

MonoInterface *InitializationInterop::monoEnv = nullptr;

const char *InitializationInterop::GetName()
{
	return "Initialization";
}

void InitializationInterop::OnRunTimeInitialized()
{
	REGISTER_METHOD(OnCompilationStartingBind);
	REGISTER_METHOD(OnCompilationCompleteBind);
	REGISTER_METHOD(GetSubscribedStagesBind);
	REGISTER_METHOD(OnInitializationStageBind);
}

void InitializationInterop::OnCompilationStartingBind()
{
	monoEnv->broadcaster->OnCompilationStarting();
}
void InitializationInterop::OnCompilationCompleteBind(bool success)
{
	monoEnv->broadcaster->OnCompilationComplete(success);
}
mono::Array InitializationInterop::GetSubscribedStagesBind()
{
	int stagesCount;
	int *indices = monoEnv->broadcaster->GetSubscribedStagesInfo(stagesCount);
	IMonoClass *SystemInt32 = MonoClassCache::Wrap(mono_get_int32_class());
	IMonoArray *result = MonoEnv->CreateArray(SystemInt32, stagesCount, false);
	for (int i = 0; i < stagesCount; i++)
	{
		result->At<int>(i) = indices[i];
	}
	return (mono::Array)result->GetWrappedPointer();
}
void InitializationInterop::OnInitializationStageBind(int stageIndex)
{
	monoEnv->broadcaster->OnInitializationStage(stageIndex);
}

void InitializationInterop::SetInterface(IMonoInterface *handle)
{
	this->monoInterface = handle;
	monoEnv = (MonoInterface *)this->monoInterface;
}

Declaration of corresponding C# class:

using System.Runtime.CompilerServices;

namespace CryCil.Interops
{
	internal static class Initialization
	{
		[MethodImpl(MethodImplOptions.InternalCall)]
		internal static extern void OnCompilationStartingBind();
		[MethodImpl(MethodImplOptions.InternalCall)]
		internal static extern void OnCompilationCompleteBind(bool success);
		[MethodImpl(MethodImplOptions.InternalCall)]
		internal static extern int[] GetSubscribedStagesBind();
		[MethodImpl(MethodImplOptions.InternalCall)]
		internal static extern void OnInitializationStageBind(int stageIndex);
	}
}
Clone this wiki locally