原文链接:https://blog.unity.com/engine-platform/il2cpp-internals-method-calls

这是 IL2CPP Internals 系列的第四篇博文。在这篇文章中,我们将了解 il2cpp.exe 如何为托管代码中的方法调用生成 C++ 代码。具体来说,我们将研究六种不同类型的方法调用:

在每种情况下,我们将重点关注生成的 C++ 代码在做什么,特别是这些指令的成本是多少。

与本系列中的所有文章一样,我们将探讨的代码可能会发生变化,事实上,在更新的 Unity 版本中也可能会发生变化。但是,概念应该保持不变。请将本系列中讨论的所有内容视为实现细节。不过,在可能的情况下,我们还是喜欢揭示和讨论这样的细节!

Setup

我将使用 Unity 5.0.1p4 版本。我将在 Windows 上运行编辑器,并为 WebGL 平台构建。我将启用 "Development Player "选项,并将 "Enable Exceptions "选项设置为 "Full"。

我将使用一个脚本文件进行构建,该文件是在上一篇文章的基础上修改的,这样我们就可以看到不同类型的方法调用。脚本以一个接口和类的定义开始:

interface Interface {
	int MethodOnInterface(string question);
}

class Important : Interface {
	public int Method(string question) { return 42; }
	public int MethodOnInterface(string question) { return 42; }
	public static int StaticMethod(string question) { return 42; }
}

然后,我们有一个常量字段和一个委托类型,两者都将在后面的代码中使用:

private const string question = "What is the answer to the ultimate question of life, the universe, and everything?";

private delegate int ImportantMethodDelegate(string question);

最后,这些就是我们有兴趣探索的方法,以及一个空的 start 方法:

private void CallDirectly() {
	var important = ImportantFactory();
	important.Method(question);
}

private void CallStaticMethodDirectly() {
	Important.StaticMethod(question);
}

private void CallViaDelegate() {
	var important = ImportantFactory();
	ImportantMethodDelegate indirect = important.Method;
	indirect(question);
}

private void CallViaRuntimeDelegate() {
	var important = ImportantFactory();
	var runtimeDelegate = Delegate.CreateDelegate(typeof (ImportantMethodDelegate), important, "Method");
	runtimeDelegate.DynamicInvoke(question);
}

private void CallViaInterface() {
	Interface importantViaInterface = new Important();
	importantViaInterface.MethodOnInterface(question);
}

private void CallViaReflection() {
	var important = ImportantFactory();
	var methodInfo = typeof(Important).GetMethod("Method");
	methodInfo.Invoke(important, new object[] {question});
}

private static Important ImportantFactory() {
	var important = new Important();
	return important;
}

void Start () {}

定义好这些后,让我们开始吧。请记住,生成的 C++ 代码将位于项目中的 Temp\StagingArea\Data\il2cppOutput 目录中(只要编辑器保持打开)。别忘了在生成的代码上生成 Ctags,以帮助导航。

Calling a method directly