前断时间做项目的时候,发现一个问题:动态导入的dll(即打包成exe后再放入包中的dll),unity提供的特性RuntimeInitializeOnLoadMethod标注的方法没有被调用。
代码很简单,只是测试用,如下:
namespace TestProject
{
public class Test
{
[RuntimeInitializeOnLoadMethod]
private static void Init()
{
Debug.Log("Test.Init func");
}
}
}
Test的Init函数加上RuntimeInitializeOnLoadMethod和去掉RuntimeInitializeOnLoadMethod后分别出包,对比后发现,只有globalgamemanagers文件有不同,虽然该文件已经加密,但用BCompare打开后我们可以看到些许端倪,见下图蓝色框框处:

原来unity把有用RuntimeInitializeOnLoadMethod的相关信息存储在了该文件中,TestProject为dll名称,TestProject.Test为命名空间,Init为使用到特性的函数。
这是一个聪明的做法,大家都知道C#的反射是很耗费时间的,如果不把上面的信息提前存储起来,而等到运行时再加载所有的dll,得到所有的Type,一个一个的函数查询有没有用到RuntimeInitializeOnLoadMethod的话,那效率肯定是非常感人的。所以Unity把这部分时间分摊到了编辑期,每把一个dll考入unity工程或者有改变dll时,Unity都会对其进行分析,然后把感兴趣的内容存储起来,运行时根据这些内容,精确的找到相应的点,执行就好了(笔者自行yy的)。
那具体是怎么做的呢?其实很简单,我们一起来实现这个功能:
就是用到了一些c#反射的知识,获取RuntimeInitializeOnLoadMethod实现思路是这样的:在某个时机点,获取出所有感兴趣的dll--》依次加载dll--》得到dll中所有的Type--》获取这个Type下所有的Static函数--》判断该static函数是否有用到R

本文介绍了如何在Unity中动态导入DLL并在运行时调用标记了RuntimeInitializeOnLoadMethod特性的静态方法。通过分析Unity的工作原理,展示了如何利用反射和特定的数据结构来收集和调用这些方法,强调了使用静态方法的原因和其带来的效率提升。
最低0.47元/天 解锁文章
844

被折叠的 条评论
为什么被折叠?



