原文链接:https://blog.unity.com/engine-platform/il2cpp-internals-method-calls
这是 IL2CPP Internals 系列的第四篇博文。在这篇文章中,我们将了解 il2cpp.exe 如何为托管代码中的方法调用生成 C++ 代码。具体来说,我们将研究六种不同类型的方法调用:
在每种情况下,我们将重点关注生成的 C++ 代码在做什么,特别是这些指令的成本是多少。
与本系列中的所有文章一样,我们将探讨的代码可能会发生变化,事实上,在更新的 Unity 版本中也可能会发生变化。但是,概念应该保持不变。请将本系列中讨论的所有内容视为实现细节。不过,在可能的情况下,我们还是喜欢揭示和讨论这样的细节!
我将使用 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,以帮助导航。