游戏开发者联盟

[pinvoke]Unity动态加载Native插件

用c写的dll,Unity在加载以后,永不卸载,官方说要想卸载只能重启。改个bug、加两行代码重启一下Unity等几分钟,不能接受。

最后找到了一篇文章,介绍了如何动态加载、卸载。如下:

Update C++ Without Restarting the Editor

我在这篇文章的基础上,增加了自动初始化delegate的功能,减少一些重复代码。

其次,在开发时我没有把dll复制到Plugin目录,而是在在代码中直接指向vs编译出来的路径。

此时,调用Native插件就跟普通windows程序调用普通dll一样,可以方便的重新编译、加载。

delegate自动初始化

public class Ezg
{
        //delegate有固定的开头和结束标志,初始化时,根据这些特征,只初始化这些字段。
        public delegate void ezg_SetLogCallback_Dg(IntPtr cb);
        public static ezg_SetLogCallback_Dg ezg_SetLogCallback;

        static Ezg()
        {
            LoadDll();
        }

        public static Dg GetDllFunc<Dg>() where Dg : class
        {
            string name = typeof(Dg).Name;
            name = name.Substring(0, name.LastIndexOf("_Dg"));
            return DllLoader.GetDelegate<Dg>(libraryHandle, name);
        }


        static void LoadDll()
        {
            var type = typeof(Ezg);
            var fields = type.GetFields();
            foreach (var one in fields)
            {
                var fieldType = one.FieldType;
                if (fieldType.Name.StartsWith("ezg_") && fieldType.Name.EndsWith("Dg"))
                {
                    var dllfunc = type.GetMethod("GetDllFunc").MakeGenericMethod(fieldType).Invoke(null, new object[] { });
                    one.SetValue(null, dllfunc);
                }
            }
        }
}

关键点

2020.7.10更新

  1. 放入Plugins目录中的dll不能重新加载
    放入unity Plugins中以后,unity会自动加载它、并锁定,导致在unity重启之前无法更新。
  2. 如果dll代码中启动了线程,也会阻止dll卸载。
    想办法在卸载之前停止它所启动的线程。这个花了我不少时间才意识到的。

第三方插件

2020.5.10更新
这两种插件,工作都不是很稳定。如果时不时的不能编译cpp dll会让人心情烦躁。
两个动态更新插件