国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

這篇具有很好參考價(jià)值的文章主要介紹了Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1.什么是熱更新

熱更新是指在不需要重新編譯打包游戲的情況下,在線更新游戲中的一些非核心代碼和資源,比如活動(dòng)運(yùn)營和打補(bǔ)丁。熱更新分為資源熱更新和代碼熱更新兩種,代碼熱更新實(shí)際上也是把代碼當(dāng)成資源的一種熱更新,但通常所說的熱更新一般是指代碼熱更新。資源熱更新主要通過AssetBundle來實(shí)現(xiàn),在Unity編輯器內(nèi)為游戲中所用到的資源指定AB包的名稱和后綴,然后進(jìn)行打包并上傳服務(wù)器,待游戲運(yùn)行時(shí)動(dòng)態(tài)加載服務(wù)器上的AB資源包。代碼熱更新主要包括Lua熱更新、ILRuntime熱更新和C#直接反射熱更新等。由于ILRuntime熱更新還不成熟可能存在一些坑,而C#直接反射熱更新又不支持IOS平臺(tái),因此目前大多采用更成熟的、沒有平臺(tái)限制的Lua熱更新方案。

2.為什么要有熱更新

熱更新,能夠縮短用戶取得新版客戶端的流程,改善用戶體驗(yàn)。

沒有熱更新:

pc用戶:下載客戶端->等待下載->安裝客戶端->等待安裝->啟動(dòng)->等待加載->玩

手機(jī)用戶:商城下載APP->等待下載->等待安裝->啟動(dòng)->等待加載->玩

有了熱更新:

pc用戶:啟動(dòng)->等待熱更新->等待加載->玩

有獨(dú)立loader的pc用戶:啟動(dòng)loader->等待熱更新->啟動(dòng)游戲->等待加載->玩

手機(jī)用戶:啟動(dòng)->等待熱更新->等待加載->玩

通過對(duì)比就可以看出,有沒有熱更新對(duì)于用戶體驗(yàn)的影響還是挺大的,主要就是省去用戶自行更新客戶端的步驟。

3.如何使用熱更新,使用熱更新的不同方案比較

3.1.LUA熱更(LUA與C#綁定,方案成熟)

Lua熱更新解決方案是通過一個(gè)Lua熱更新插件(如ulua、slua、tolua、xlua等)來提供一個(gè)Lua的運(yùn)行環(huán)境以及和C#進(jìn)行交互。xLua是騰訊開源的熱更新插件,有大廠背書和專職人員維護(hù),插件的穩(wěn)定性和可持續(xù)性較強(qiáng)。?

由于Lua不需要編譯,因此Lua代碼可以直接在Lua虛擬機(jī)里運(yùn)行,Python和JavaScript等腳本語言也是同理。而xLua熱更新插件就是為Unity、.Net、Mono等C#環(huán)境提供一個(gè)Lua虛擬機(jī),使這些環(huán)境里也可以運(yùn)行Lua代碼,從而為它們?cè)黾覮ua腳本編程的能力。借助xLua,這些Lua代碼就可以方便的和C#相互調(diào)用。這樣平時(shí)開發(fā)時(shí)使用C#,等需要熱更新時(shí)再使用Lua,等下次版本更新時(shí)再把之前的Lua代碼轉(zhuǎn)換成C#代碼,從而保證游戲正常運(yùn)營。

其中的XLua下文會(huì)重點(diǎn)討論。

lua熱更原理:邏輯代碼轉(zhuǎn)化為腳本,腳本轉(zhuǎn)化為文本資源,以更新資源的形式更新程序

?一位老哥做的Xlua性能測(cè)試:

XLua 性能測(cè)試_tian2kong的專欄-CSDN博客_xlua性能優(yōu)化這個(gè)一段代碼,運(yùn)行的性能分析是這樣的這個(gè)代碼是我用lua寫的,其他的環(huán)境是一樣,就是這個(gè)代碼差別,一個(gè)用lua寫,一個(gè)C#寫,運(yùn)行的分析圖是這樣的從這個(gè)兩個(gè)分析圖,我們可以看出,就Translate這個(gè)api函數(shù),一個(gè)在C#調(diào)用,一個(gè)在xlua調(diào)用,如果數(shù)量級(jí)多的話,性能上還是差別很大的所以我個(gè)人覺得,如果是UI用xlua實(shí)現(xiàn)沒有大問題,如果是在戰(zhàn)斗中,盡量不要再Xlua的update中取實(shí)現(xiàn)功能...https://blog.csdn.net/tian2kong/article/details/79423848這位老哥,用一個(gè)同樣的函數(shù),用C#寫的運(yùn)行10.68ms,用Xlua寫的運(yùn)行37.29ms。可見Xlua性能上還是差別很大的。后文將繼續(xù)研究為什么Xlua性能更差。

3.2 .ILRuntime熱更

ILRuntime項(xiàng)目是掌趣科技開源的熱更新項(xiàng)目,它為基于C#的平臺(tái)(例如Unity)提供了一個(gè)純C#、快速、方便和可靠的IL運(yùn)行時(shí),使得能夠在不支持JIT的硬件環(huán)境(如iOS)能夠?qū)崿F(xiàn)代碼熱更新。ILRuntime項(xiàng)目的原理實(shí)際上就是先用VS把需要熱更新的C#代碼封裝成DLL(動(dòng)態(tài)鏈接庫)文件,然后通過Mono.Cecil庫讀取DLL信息并得到對(duì)應(yīng)的IL中間代碼(IL是.NET平臺(tái)上的C#、F#等高級(jí)語言編譯后產(chǎn)生的中間代碼,IL的具體形式為.NET平臺(tái)編譯后得到的.dll動(dòng)態(tài)鏈接庫文件或.exe可執(zhí)行文件),最后再用內(nèi)置的IL解譯執(zhí)行虛擬機(jī)來執(zhí)行DLL文件中的IL代碼。

由于ILRuntime項(xiàng)目是使用C#來完成熱更新,因此很多時(shí)候會(huì)用到反射來實(shí)現(xiàn)某些功能。而反射是.NET平臺(tái)在運(yùn)行時(shí)獲取類型(包括類、接口、結(jié)構(gòu)體、委托和枚舉等類型)信息的重要機(jī)制,即從對(duì)象外部獲取內(nèi)部的信息,包括字段、屬性、方法、構(gòu)造函數(shù)和特性等。我們可以使用反射動(dòng)態(tài)獲取類型的信息,并利用這些信息動(dòng)態(tài)創(chuàng)建對(duì)應(yīng)類型的對(duì)象。只不過ILRuntime中的反射有兩種:一種是在熱更新DLL中直接使用C#反射獲取到System.Type類對(duì)象;另一種是在Unity主工程中通過appdomain.LoadedTypes來獲取繼承自System.Type類的IType類對(duì)象,因?yàn)樵赨nity主工程中無法直接通過System.Type類來獲取熱更新DLL中的類。

ILRuntime下文也會(huì)重點(diǎn)討論。

ILRuntime項(xiàng)目為基于C#的平臺(tái)(例如Unity)提供了一個(gè)純C#實(shí)現(xiàn),快速、方便可靠IL運(yùn)行時(shí)(后文詳細(xì)了解),使得能夠在不支持JIT的硬件環(huán)境(如iOS)(后文詳細(xì)了解)能夠?qū)崿F(xiàn)代碼的熱更新。

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

3.3.直接更dll(IOS不能用)

由于Android支持JIT(Just In Time)即時(shí)編譯(動(dòng)態(tài)編譯)的模式,即可以邊運(yùn)行邊編譯,支持在運(yùn)行時(shí)動(dòng)態(tài)生成代碼和類型。從Android N開始引入了一種同時(shí)使用JIT和AOT的混合編譯模式。JIT的優(yōu)點(diǎn)是支持在運(yùn)行時(shí)動(dòng)態(tài)生成代碼和類型,APP安裝快,不占用太多內(nèi)存。缺點(diǎn)是編譯時(shí)占用運(yùn)行時(shí)資源,執(zhí)行速度比AOT慢。比如,C#中的虛函數(shù)和反射都是在程序運(yùn)行時(shí)才確定對(duì)應(yīng)的重載方法和類。因此,Android平臺(tái)可以不借助任何第三方熱更新方案,直接使用C#反射執(zhí)行DLL文件。實(shí)際開發(fā)時(shí)通過System.Reflection.Assembly類加載程序集DLL文件,然后再利用System.Type類獲取程序集中某個(gè)類的信息,還可以通過Activator類來動(dòng)態(tài)創(chuàng)建實(shí)例對(duì)象。

而IOS平臺(tái)采用AOT(Ahead Of Time)預(yù)先編譯(靜態(tài)編譯)的模式,不支持JIT編譯模式,即程序運(yùn)行前就將代碼編譯成機(jī)器碼存儲(chǔ)在本地,然后運(yùn)行時(shí)直接執(zhí)行即可,因此AOT不能在運(yùn)行時(shí)動(dòng)態(tài)生成代碼和類型。AOT的優(yōu)點(diǎn)是執(zhí)行速度快,安全性更高。缺點(diǎn)是由于AOT需要提前編譯,所以APP的安裝時(shí)間長且占內(nèi)存。Mono在IOS平臺(tái)上采用Full AOT模式運(yùn)行,如果直接使用C#反射執(zhí)行DLL文件,就會(huì)觸發(fā)Mono的JIT編譯器,而Full AOT模式下又不允許JIT,于是Mono就會(huì)報(bào)錯(cuò)。因此,IOS平臺(tái)上不允許直接使用C#反射執(zhí)行DLL文件來實(shí)現(xiàn)熱更新。

將執(zhí)行代碼預(yù)編譯為assembly?dll。將代碼作為TextAsset打包進(jìn)Assetbundle。運(yùn)行時(shí),使用Reflection機(jī)制實(shí)現(xiàn)代碼的功能。更新相應(yīng)的Assetbundle即可實(shí)現(xiàn)熱更新。(具體技術(shù)細(xì)節(jié),后文討論)

4.Xlua源碼實(shí)現(xiàn)

4.0 Xlua的特性

xLua為C#環(huán)境增加Lua腳本編程的能力,借助xLua,這些Lua代碼可以方便的和C#相互調(diào)用。

Xlua可以:?

  • 1.可以運(yùn)行時(shí)把C#實(shí)現(xiàn)(方法,操作符,屬性,事件等等)替換成lua實(shí)現(xiàn);
  • 2.出色的GC優(yōu)化,自定義struct,枚舉在Lua和C#間傳遞無C# gc alloc;
  • 3.編輯器下無需生成代碼,開發(fā)更輕量;
  • 4.為很多C#實(shí)現(xiàn)打熱補(bǔ)丁

4.1 Xlua的使用

4.1.1?Lua文件加載

luaenv = new LuaEnv();
luaenv.DoString("print('hello world')");

4.1.2?加載Lua文件

            luaenv = new LuaEnv();
            luaenv.DoString("require 'byfile'");

require實(shí)際上是調(diào)一個(gè)個(gè)的原生的loader去加載,有一個(gè)成功就不再往下嘗試,全失敗則報(bào)文件找不到。 目前xLua除了原生的loader外,還添加了從Resource加載的loader(Xlua的一個(gè)特性,自定義loader),需要注意的是因?yàn)镽esource只支持有限的后綴,放Resources下的lua文件得加上txt后綴。

建議的加載Lua腳本方式是:整個(gè)程序就一個(gè)DoString("require 'main'"),然后在main.lua加載其它腳本(類似lua腳本的命令行執(zhí)行:lua main.lua)。

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

?4.1.3?自定義Loader

Loader運(yùn)行的時(shí)候會(huì)檢索所有的loader,這里給Loader列表,添加一個(gè)Loader,當(dāng)其他所有l(wèi)oader都找不到"InMemory"的時(shí)候,這個(gè)自定義loader就起作用了。檢測(cè)filename名稱并返回相應(yīng)的東西。

            luaenv = new LuaEnv();
            luaenv.AddLoader((ref string filename) =>
            {
                if (filename == "InMemory")
                {
                    string script = "return {ccc = 9999}";
                    return System.Text.Encoding.UTF8.GetBytes(script);
                }
                return null;
            });
            luaenv.DoString("print('InMemory.ccc=', require('InMemory').ccc)");

?4.1.4?C#訪問Lua

這里指的是C#主動(dòng)發(fā)起對(duì)Lua數(shù)據(jù)結(jié)構(gòu)的訪問。

1.全局基本數(shù)據(jù)類型:(調(diào)用LuaEnv.Global)

 luaenv.Global.Get<int>("a")
 luaenv.Global.Get<string>("b")
 luaenv.Global.Get<bool>("c")

2.訪問一個(gè)全局的table:

也是用上面的Get方法,類型則要特殊處理。

2.1 映射到普通class或struct:(其實(shí)就是Get<>中的參數(shù)填XXXClass)

            DClass d = luaenv.Global.Get<DClass>("d");//映射到有對(duì)應(yīng)字段的class,by value
            Debug.Log("_G.d = {f1=" + d.f1 + ", f2=" + d.f2 + "}");

對(duì)于{f1 = 100, f2 = 100}可以定義一個(gè)包含public int f1;public int f2;的class。 這種方式下xLua會(huì)幫你new一個(gè)實(shí)例,并把對(duì)應(yīng)的字段賦值過去。這個(gè)過程是值拷貝,如果class比較復(fù)雜代價(jià)會(huì)比較大。而且修改class的字段值不會(huì)同步到table,反過來也不會(huì)。

2.2?映射到一個(gè)interface:

這種方式依賴于生成代碼(如果沒生成代碼會(huì)拋InvalidCastException異常),代碼生成器會(huì)生成這個(gè)interface的實(shí)例,如果get一個(gè)屬性,生成代碼會(huì)get對(duì)應(yīng)的table字段,如果set屬性也會(huì)設(shè)置對(duì)應(yīng)的字段。甚至可以通過interface的方法訪問lua的函數(shù)。(這個(gè)要求interface加到生成列表,否則會(huì)返回null

本來interface不能直接生成實(shí)例的,這里給直接生成實(shí)例了。

            ItfD d3 = luaenv.Global.Get<ItfD>("d"); //映射到interface實(shí)例,by ref,這個(gè)要求interface加到生成列表,否則會(huì)返回null,建議用法
            d3.f2 = 1000;
            Debug.Log("_G.d = {f1=" + d3.f1 + ", f2=" + d3.f2 + "}");
            Debug.Log("_G.d:add(1, 2)=" + d3.add(1, 2));

2.3?更輕量級(jí)的by value方式:映射到Dictionary<>,List<>

不想定義class或者interface的話,可以考慮用這個(gè),前提t(yī)able下key和value的類型都是一致的。

            Dictionary<string, double> d1 = luaenv.Global.Get<Dictionary<string, double>>("d");//映射到Dictionary<string, double>,by value
            Debug.Log("_G.d = {f1=" + d1["f1"] + ", f2=" + d1["f2"] + "}, d.Count=" + d1.Count);

2.4?另外一種by ref方式:映射到LuaTable類

這種方式好處是不需要生成代碼,但也有一些問題,比如慢,比方式2要慢一個(gè)數(shù)量級(jí),比如沒有類型檢查。

            LuaTable d4 = luaenv.Global.Get<LuaTable>("d");//映射到LuaTable,by ref
            Debug.Log("_G.d = {f1=" + d4.Get<int>("f1") + ", f2=" + d4.Get<int>("f2") + "}");

3.訪問一個(gè)全局的function:

3.1.映射到delegate:

這種是建議的方式,性能好很多,而且類型安全。缺點(diǎn)是要生成代碼(如果沒生成代碼會(huì)拋InvalidCastException異常)。

        [CSharpCallLua]
        public delegate int FDelegate(int a, string b, out DClass c);
            Action e = luaenv.Global.Get<Action>("e");//映射到一個(gè)delgate,要求delegate加到生成列表,否則返回null,建議用法
            e();

            FDelegate f = luaenv.Global.Get<FDelegate>("f");
            DClass d_ret;
            int f_ret = f(100, "John", out d_ret);//lua的多返回值映射:從左往右映射到c#的輸出參數(shù),輸出參數(shù)包括返回值,out參數(shù),ref參數(shù)
            Debug.Log("ret.d = {f1=" + d_ret.f1 + ", f2=" + d_ret.f2 + "}, ret=" + f_ret);

?或者:

        [CSharpCallLua]
        public delegate Action GetE();
            GetE ret_e = luaenv.Global.Get<GetE>("ret_e");//delegate可以返回更復(fù)雜的類型,甚至是另外一個(gè)delegate
            e = ret_e();
            e();

?3.2.映射到LuaFunction

這種方式的優(yōu)缺點(diǎn)剛好和第一種相反。性能差類型不安全,但是不用生成代碼。 使用也簡單,LuaFunction上有個(gè)變參的Call函數(shù),可以傳任意類型,任意個(gè)數(shù)的參數(shù),返回值是object的數(shù)組,對(duì)應(yīng)于lua的多返回值。

            LuaFunction d_e = luaenv.Global.Get<LuaFunction>("e");
            d_e.Call();

會(huì)返回[object,object,object] 的列表,對(duì)應(yīng)lua函數(shù)返回多個(gè)值

4.注意事項(xiàng)

4.1 訪問lua全局?jǐn)?shù)據(jù),特別是table以及function,代價(jià)比較大,建議盡量少做,比如在初始化時(shí)把要調(diào)用的lua function獲取一次(映射到delegate)后,保存下來,后續(xù)直接調(diào)用該delegate即可。table也類似。

4.2如果lua側(cè)的實(shí)現(xiàn)的部分都以delegate和interface的方式提供,使用方可以完全和xLua解耦:由一個(gè)專門的模塊負(fù)責(zé)xlua的初始化以及delegate、interface的映射,然后把這些delegate和interface設(shè)置到要用到它們的地方。

4.1.5 Lua調(diào)用C#

1.new C#對(duì)象

local newGameObj = CS.UnityEngine.GameObject()

?2.訪問C#靜態(tài)屬性,方法

讀寫靜態(tài)屬性

CS.UnityEngine.Time.deltaTime
CS.UnityEngine.Time.timeScale = 0.5

調(diào)用靜態(tài)方法

CS.UnityEngine.GameObject.Find('helloworld')
//小技巧:如果需要經(jīng)常訪問的類,可以先用局部變量引用后訪問,除了減少敲代碼的時(shí)間,還能提高性能:
local GameObject = CS.UnityEngine.GameObject
GameObject.Find('helloworld')

3.訪問C#成員屬性,方法

讀寫成員屬性

testobj.DMF
testobj.DMF = 1024

調(diào)用成員方法

注意:調(diào)用成員方法,第一個(gè)參數(shù)需要傳該對(duì)象,建議用冒號(hào)語法糖,如下

testobj:DMFunc()
//等同于
testobj.DMFunc(testobj)

參數(shù)的輸入輸出屬性(out,ref)

Lua調(diào)用側(cè)的參數(shù)處理規(guī)則:C#的普通參數(shù)算一個(gè)輸入形參,ref修飾的算一個(gè)輸入形參,out不算,然后從左往右對(duì)應(yīng)lua 調(diào)用側(cè)的實(shí)參列表;

Lua調(diào)用側(cè)的返回值處理規(guī)則:C#函數(shù)的返回值(如果有的話)算一個(gè)返回值,out算一個(gè)返回值,ref算一個(gè)返回值,然后從左往右對(duì)應(yīng)lua的多返回值。

		
	public struct Param1
	{
		public int x;
		public string y;
	}

        public double ComplexFunc(Param1 p1, ref int p2, out string p3, Action luafunc, out Action csfunc)
		{
			Debug.Log("P1 = {x=" + p1.x + ",y=" + p1.y + "},p2 = " + p2);
			luafunc();
			p2 = p2 * p1.x;
			p3 = "hello " + p1.y;
			csfunc = () =>
			{
				Debug.Log("csharp callback invoked!");
			};
			return 1.23;
		}
            --復(fù)雜方法調(diào)用
            local ret, p2, p3, csfunc = testobj:ComplexFunc({x=3, y = 'john'}, 100, function()
               print('i am lua callback')
            end)
            print('ComplexFunc ret:', ret, p2, p3, csfunc)
            csfunc()

4.C#復(fù)雜類型和table的自動(dòng)轉(zhuǎn)換

對(duì)于一個(gè)有無參構(gòu)造函數(shù)的C#復(fù)雜類型,在lua側(cè)可以直接用一個(gè)table來代替,該table對(duì)應(yīng)復(fù)雜類型的public字段有相應(yīng)字段即可,支持函數(shù)參數(shù)傳遞,屬性賦值等,例如: C#下B結(jié)構(gòu)體(class也支持)定義如下:

public struct A
{
    public int a;
}

public struct B
{
    public A b;
    public double c;
}

某個(gè)類有成員函數(shù)如下:

void Foo(B b)

在lua可以這么調(diào)用

obj:Foo({b = {a = 100}, c = 200})

5.獲取類型(相當(dāng)于C#的typeof)

typeof(CS.UnityEngine.ParticleSystem)

6.“強(qiáng)”轉(zhuǎn)

lua沒類型,所以不會(huì)有強(qiáng)類型語言的“強(qiáng)轉(zhuǎn)”,但有個(gè)有點(diǎn)像的東西:告訴xlua要用指定的生成代碼去調(diào)用一個(gè)對(duì)象,這在什么情況下能用到呢?有的時(shí)候第三方庫對(duì)外暴露的是一個(gè)interface或者抽象類,實(shí)現(xiàn)類是隱藏的,這樣我們無法對(duì)實(shí)現(xiàn)類進(jìn)行代碼生成。該實(shí)現(xiàn)類將會(huì)被xlua識(shí)別為未生成代碼而用反射來訪問,如果這個(gè)調(diào)用是很頻繁的話還是很影響性能的,這時(shí)我們就可以把這個(gè)interface或者抽象類加到生成代碼,然后指定用該生成代碼來訪問:

cast(calc, typeof(CS.Tutorial.Calc))

上面就是指定用CS.Tutorial.Calc的生成代碼來訪問calc對(duì)象。

            //通過反射來調(diào)用函數(shù)
            local calc = testobj:GetCalc()
            print('assess instance of InnerCalc via reflection', calc:add(1, 2))
            assert(calc.id == 100)

            //把這個(gè)interface或者抽象類加到生成代碼,然后指定用該生成代碼來訪問
            cast(calc, typeof(CS.Tutorial.ICalc))
            print('cast to interface ICalc', calc:add(1, 2))
            assert(calc.id == nil)

4.2 Xlua具體代碼的實(shí)現(xiàn)與原理

4.2.1 Xlua中?lua調(diào)用c#的原理:

如果一個(gè)C#類型添加了[LuaCallCSharp]標(biāo)簽,xLua會(huì)生成這個(gè)類型的XXXXXWrap.cs適配代碼(包括構(gòu)造該類型實(shí)例,訪問其成員屬性、方法,靜態(tài)屬性、方法),并用luaAPI放到lua的堆棧里面。如果沒有提前生成適配代碼,等程序運(yùn)行,lua調(diào)用c#的時(shí)候,就會(huì)用性能較低反射方式來訪問,把c#類用反射全部遍歷一遍,然后再放入lua的堆棧中。(反射比普通方法慢10000倍)

而且在IL2CPP下還有可能因?yàn)榇a剪裁而導(dǎo)致無法訪問。IL2CPP是Unity推出的用來替代Mono VM的編譯器。

初始化過程:

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

DelegatesGensBridge.cs :Xlua生成這個(gè)文件,是用來指向 “hotfix熱更新中,lua替代掉c#的方法函數(shù)?!? EnumWrap.cs: 把枚舉都遍歷一遍,存到EnumWrap.cs中,之后放入lua堆棧中。 XXXXXWrap.cs適配代碼:把lua需要調(diào)用的方法存到適配代碼中,之后放入Lua堆棧中。)

lua調(diào)用C#的過程:?

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

?4.2.2 Xlua中 c#調(diào)用lua的原理

如果C#想要訪問Lua中函數(shù)或Table,就要在C#中對(duì)應(yīng)的DelegateInterface添加?[CSharpCallLua]標(biāo)簽。Xlua會(huì)生成相應(yīng)的XXXXXBridge.cs文件,會(huì)把lua中相應(yīng)的函數(shù)方法,映射到c#中相應(yīng)的Delegate或Interface中,然后通過luaenv.Global來調(diào)用。盡管還有其他映射方式,但最好通過Delegate來映射Lua中的函數(shù),通過Interface來映射Lua中的Table。

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

?4.2.3 Xlua中 Hotfix原理

生成XXXXXWrap.cs適配器代碼后,執(zhí)行XLua/Hotfix inject in Editor后,xLua會(huì)使用Mono.Cecil庫對(duì)當(dāng)前工程下的Assembly-CSharp.dll程序集進(jìn)行IL注入。由于移動(dòng)平臺(tái)無法把C#代碼編譯成IL中間代碼,所以絕大多數(shù)熱更新方案都會(huì)涉及到IL注入(啥意思?理解不了這句,直接跳過。),只有這樣Unity內(nèi)置的VM才能對(duì)熱更新的代碼進(jìn)行處理。xLua進(jìn)行IL注入時(shí)會(huì)為打上[Hotfix]標(biāo)簽的類的所有函數(shù)創(chuàng)建一個(gè)DelegateBridge變量,同時(shí)添加對(duì)應(yīng)的判斷條件,有hotfix代碼就執(zhí)行l(wèi)ua的hotfix代碼,沒有hotfix代碼就執(zhí)行原來的c#代碼。

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

4.3 Xlua中 其他問題

1.luaenv的原理是什么?

luaenv是Xlua中的一個(gè)Lua虛擬機(jī)類,用來執(zhí)行l(wèi)ua代碼,或者管理Lua堆棧。

Lua初學(xué)者(四)--Lua調(diào)用原理展示(lua的堆棧)_豬豬俠的點(diǎn)滴-CSDN博客_lua棧本文較詳細(xì)的描述了 宿主語言(這里拿C++實(shí)例) 調(diào)用 Lua 時(shí)過程中的 棧的使用情況,最后附圖 動(dòng)態(tài) 展示整個(gè)過程。希望對(duì)大家提供幫助。https://blog.csdn.net/zhuzhuyule/article/details/41086745?utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.control

2.DoStrnig的原理是什么?

讓Xlua中的luaenv虛擬機(jī),執(zhí)行DoString中的代碼。

3.自定義Loader的原理是什么?

通過LuaEnv.AddLoader以及LuaAPI注冊(cè)require的回調(diào),lua代碼里頭調(diào)用require時(shí),參數(shù)將會(huì)透傳給回調(diào),回調(diào)中就可以根據(jù)這個(gè)參數(shù)去加載指定文件。

4.Lua映射到C#的class原理是什么?

通過為每個(gè)CShapeCallLua生成對(duì)應(yīng)的XXXXXBridge.cs文件,然后通過LuaAPI對(duì)對(duì)應(yīng)的lua函數(shù)具體部分進(jìn)行操作,讓C#中的函數(shù)和lua中的函數(shù)對(duì)應(yīng)起來。

5.代碼生成器是啥概念?

Xlua中的Generator.cs類,能根據(jù)模板,例如LuaClassWrap.tpl.txt,來生成具體的.cs或者.lua或者.xml文件。

6.為啥Lua映射到C#的LuaTable類會(huì)比映射到一個(gè)interface代碼生成器慢一個(gè)數(shù)量級(jí)?

這種泛而全的LuaTable類,要把Lua映射上去,必定要對(duì)lua方法進(jìn)行反射操作,反射又是十分耗時(shí)的。不如直接用代碼生成器,提前生成好XXXXBridge.cs,直接照著Bridge.cs中的結(jié)構(gòu),用LuaAPI填數(shù)據(jù)進(jìn)去,這樣速度快非常多。

7 by ref方式映射又是啥?

by ref就是by reference,引用傳遞的意思。Xlua官方源碼案例中,直接搜by ref能看到案例。

8.為什么訪問lua全局?jǐn)?shù)據(jù),特別是table以及function,代價(jià)比較大

這個(gè)問題網(wǎng)上的答案也是眾說紛紜,短期內(nèi)我也找不到好的解答。問題肯定出在存全局和存局部的數(shù)據(jù)結(jié)構(gòu),堆棧中的配置方法不一樣導(dǎo)致的。可能是全局?jǐn)?shù)據(jù)需要掃描所有堆棧,而局部數(shù)據(jù)知道了入口以及數(shù)據(jù)量大小,只要掃描局部小部分。

9.lua調(diào)用C#中的CS.是什么原理?

生成XXXXBridge.cs,然后用luaAPI進(jìn)行映射。前文有具體說明。

10.為什么先用局部變量引用后訪問,能提高性能?

因?yàn)槿肿兞吭L問慢,用局部引用后,訪問局部就快了。

11.語法糖的冒號(hào)testobj:DMFunc()是怎么實(shí)現(xiàn)的?

冒號(hào)這個(gè),是Lua自身的特性,不是Xlua特有的東西。

1、定義的時(shí)候:Class:test()與 Class.test(self)是等價(jià)的,點(diǎn)號(hào)(.)要達(dá)到冒號(hào)(:)的效果要加一個(gè)self參數(shù)到第一個(gè)參數(shù);
2、調(diào)用的時(shí)候:object:test() 與object.test(object)等價(jià),點(diǎn)號(hào)(.)要添加對(duì)象自身到第一個(gè)參數(shù)。

總結(jié):可以把點(diǎn)號(hào)(.)作為靜態(tài)方法來看待,冒號(hào)(:)作為成員方法來看待。

12 泛化(模版)方法 是什么?Extension methods功能進(jìn)行封裝又是什么?

泛化編程,和模板是一個(gè)編程的概念。泛型編程:編寫與類型無關(guān)的通用代碼,是代碼復(fù)用的一種手段。模板是泛型編程的基礎(chǔ)。

泛化編程和模板的使用_ice_玖聞?dòng)谑镭嫉牟┛?CSDN博客_編程泛化在學(xué)習(xí)的過程中,我們?cè)趯懘a的時(shí)候會(huì)使用一些形式相同,參數(shù)相同,但參數(shù)類型和返回值類型不同的一些函數(shù)。當(dāng)初我們學(xué)過函數(shù)重載,但函數(shù)重載存在以下一些不好的地方。-例如:重載的函數(shù)僅僅只是類型不同,代碼的復(fù)用率比較低,只要有新類型出現(xiàn)時(shí),就需要增加對(duì)應(yīng)的函數(shù)。代碼的可維護(hù)性比較低,一個(gè)出錯(cuò)可能所有的重載均出錯(cuò)。泛型編程:編寫與類型無關(guān)的通用代碼,是代碼復(fù)用的一種手段。模板是泛型編程的...https://blog.csdn.net/weixin_42357849/article/details/105492332?用泛化編程的理念,來對(duì)Extension methods擴(kuò)展功能,進(jìn)行一下封裝,簡化了擴(kuò)展功能的實(shí)現(xiàn)。

13.il2cpp是什么?

IL2CPP 是 Unity一種新的腳本后處理(Scripting Backend)方式,針對(duì).Net平臺(tái)編譯輸出的IL(中間語言)進(jìn)行處理。

IL2CPP主要由兩部分組成:

  1. AOT靜態(tài)編譯編譯器(il2cpp.exe)
  2. 運(yùn)行時(shí)庫(libil2cpp)

其中AOT將IL轉(zhuǎn)換為C++源碼,再交給各平臺(tái)的C++編譯器進(jìn)行編譯,達(dá)到平臺(tái)兼容的目的;運(yùn)行時(shí)庫則會(huì)提供諸如垃圾回收、線程/文件獲取、內(nèi)部調(diào)用直接修改托管數(shù)據(jù)結(jié)構(gòu)的原生代的服務(wù)與抽象。

Unity之IL2CPP - 知乎作者:羅鵬背景在Unity4.6.1 p5以后版本中,在PlayerSettings—>Other Settings—>Scripting Backend有mono和il2cpp兩個(gè)選項(xiàng),它們是Unity腳本后處理(Scripting Backend)的兩種方式。 概念I(lǐng)L2CPP 是 Unity…https://zhuanlan.zhihu.com/p/141748334

16.c#的標(biāo)簽

[CSharpCallLua] 這種標(biāo)簽,其實(shí)是

c#中的attribute的一種應(yīng)用

C# 特性(Attribute) | 菜鳥教程C# 特性(Attribute) 特性(Attribute)是用于在運(yùn)行時(shí)傳遞程序中各種元素(比如類、方法、結(jié)構(gòu)、枚舉、組件等)的行為信息的聲明性標(biāo)簽。您可以通過使用特性向程序添加聲明性信息。一個(gè)聲明性標(biāo)簽是通過放置在它所應(yīng)用的元素前面的方括號(hào)([ ])來描述的。 特性(Attribute)用于添加元數(shù)據(jù),如編譯器指令和注釋、描述、方法、類等其他信息。.Net 框架提供了兩種類型的特性:預(yù)定義特性和自定義特性。 規(guī)定特性(Att..https://www.runoob.com/csharp/csharp-attribute.html

17.Lua調(diào)用c#,使用反射方法的時(shí)候,l2cpp下還有可能因?yàn)榇a剪裁,這是什么?link.xml阻止il2cpp的代碼剪裁怎么做到的?

什么是代碼裁剪?
關(guān)于代碼裁剪的說明: Unity - Manual: Managed code stripping

勾選代碼裁剪,構(gòu)建時(shí)Unity代碼裁剪工具會(huì)分析項(xiàng)目中的程序集,查找和刪除未使用的代碼. 裁剪掉沒有使用到的代碼.比如,一款2D游戲只用到了Sprite, 2D物理組件, 就可以把沒有用到的3D物理代碼部分裁剪掉. 使用裁剪功能可以顯著減小包體大小, 也是目前Unity游戲包體優(yōu)化的一個(gè)重要環(huán)節(jié).

看起來確實(shí)是一個(gè)非常牛掰又實(shí)用的功能, 然而還有不少問題,Unity貌似只能正確裁剪那些構(gòu)建時(shí)自動(dòng)打包進(jìn)apk的預(yù)制體和場(chǎng)景中的腳本. 而AssetBundle上的腳本就就不會(huì)被處理到, 也就是說如果Prefab被打包成AssetBundle, 這個(gè)Prefab上的代碼可能會(huì)被裁剪掉, 導(dǎo)致運(yùn)行的時(shí)候報(bào)錯(cuò)閃退, 這無疑是致命的。所以Unity提供了裁剪等級(jí)的設(shè)置, 以及通過配置link.xml告訴Unity需要保留哪些代碼.
Unity IL2CPP發(fā)布64位,以及代碼裁剪Strip Engine Code_空空如我-CSDN博客_unity 代碼裁剪關(guān)于此方面我也是最近遇到問題才剛剛接觸,有理解有誤的地方還請(qǐng)路過的看官大佬不吝賜教.Google Play要求從2019年8月1日起apk必須支持64位CPU, 否則就下架或不讓上. 使apk支持ARM64就需要把Scripting Backend由Mono切換為IL2CPP那么問題來了, 通過IL2CPP打出的包往往不能正常運(yùn)行(閃退,報(bào)錯(cuò)).其原因就是, BuildSettin...https://blog.csdn.net/final5788/article/details/100183528

18.XLua.GCOptimize,C#枚舉值加上了這個(gè)配置。xLua會(huì)為該類型生成gc優(yōu)化代碼,效果是該值類型在lua和c#間傳遞不產(chǎn)生(C#)gc alloc,該類型的數(shù)組訪問也不產(chǎn)生gc,這段話是什么意思?

傳遞引用類型需要boxing和unboxing,產(chǎn)生gc,而傳遞值類型則不需要產(chǎn)生gc,所以xlua生成XXXbridge.cs模板,把struct里的各字段拷貝到一塊非托管內(nèi)存(Pack)(托管內(nèi)存由垃圾收集器GC)清理),以及從非托管內(nèi)存拷貝出各字段的值(UnPack),傳遞的都是值類型,所以不產(chǎn)生gc。

XLua官方demo5-避免c#和lua間值類型的GC分析_Troubledealer/uestc-CSDN博客_xlua 無gc? 代碼里的幾個(gè)標(biāo)簽解釋:? ? ? ? ?· XLua.GCOptimize: gc代碼優(yōu)化。對(duì)于一個(gè)c#純值類型(官網(wǎng)指一個(gè)只包含值類型的struct,可以嵌套其它只包含值類型的struct)或者c#枚舉值加上了這個(gè)配置,會(huì)使得該類型在lua和c#間傳遞不產(chǎn)生gc alloc,該類型的數(shù)組訪問也不會(huì)產(chǎn)生gc。? ? ? ? ?(除枚舉之外,包含無參構(gòu)造函數(shù)的復(fù)雜類型,都會(huì)生成lua table...https://blog.csdn.net/qq_31915745/article/details/79635076

20.luajit是什么?

LuaJIT即采用C語言寫的Lua代碼的解釋器。

LuaJIT is a?Just-In-Time Compiler?for the Lua* programming language.

21.如何復(fù)現(xiàn)XLua的配置

直接在/Editor中新建一個(gè)靜態(tài)列表,打上LuaCallCSharp標(biāo)簽。里面的typeof(xxx)內(nèi)容就是要Lua調(diào)用Cs的函數(shù)。

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

22.如何復(fù)現(xiàn)熱補(bǔ)丁操作指南

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

24.如何復(fù)現(xiàn)XLua增加刪除第三方lua庫

參考這篇文章,照做就行。

xlua 集成rapidjson_塵封的羽翼-CSDN博客_lua-rapidjson1、結(jié)合https://blog.csdn.net/wanzhihui0000/article/details/105603317

25.如何復(fù)現(xiàn)生成引擎二次開發(fā)指南

根據(jù)模板生成link.xml文件

目錄Xlua/Src/Editor/LinkXmlGen/LinkXmlGen.cs(功能文件)和

Xlua/Src/Editor/LinkXmlGen/LinkXmlGen.tpl.txt(模板文件)

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

模板文件其中的ForEachCsList函數(shù),是個(gè)普通的lua函數(shù),編寫在TemplateCommon.lua.txt文件中。

而<%XXXXX%>中間的lua代碼,都是會(huì)直接執(zhí)行的。其余的則直接打印

?Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

?Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

?Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

點(diǎn)擊生成link.xml。?

26.由于ios的限制我們的lua虛擬機(jī)加載不了動(dòng)態(tài)庫,而是直接編譯進(jìn)進(jìn)程里頭。lua虛擬機(jī)是啥?加載動(dòng)態(tài)庫又是啥?編譯進(jìn)進(jìn)程頭又是啥?

虛擬機(jī):用于模擬計(jì)算機(jī)運(yùn)行的程序.是個(gè)中間層,它處于腳本語言和硬件之間的一個(gè)程序。

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

?VM就是虛擬機(jī)的意思。luaenv是Xlua中的一個(gè)Lua虛擬機(jī)類。

靜態(tài)庫特點(diǎn)(linux):

命名上是以 *.o 結(jié)尾
靜態(tài)庫在鏈接階段直接就加入到可執(zhí)行的文件中了,在執(zhí)行過程中無需該靜態(tài)庫
相對(duì)于動(dòng)態(tài)庫生成的文件,使用靜態(tài)庫生成的文件連接生成的可執(zhí)行文件較大
動(dòng)態(tài)庫的特點(diǎn)(linux)

命名上是以 *.so
目標(biāo)文件在鏈接階段只是指明鏈接的那個(gè)動(dòng)態(tài)庫,動(dòng)態(tài)庫與目標(biāo)文件保持獨(dú)立。在執(zhí)行過程中需要該動(dòng)態(tài)庫
使用動(dòng)態(tài)庫生成的目標(biāo)文件較小
對(duì)于工程中比較共通的源碼文件,比如多個(gè)進(jìn)程使用同一個(gè)模塊的源碼,我們最好將其制作成動(dòng)態(tài)庫,以節(jié)省系統(tǒng)空間。同時(shí)如果動(dòng)態(tài)庫出現(xiàn)bug,只需要重新生成一個(gè)動(dòng)態(tài)庫并將以前的替換即可。不需要重新編譯其他模塊。
動(dòng)態(tài)庫_xiaoxiongxiongshi的博客-CSDN博客_動(dòng)態(tài)庫總結(jié)一:動(dòng)態(tài)庫前言?我們知道程序編譯鏈接經(jīng)常使用動(dòng)態(tài),同時(shí)我們可能還知道,動(dòng)態(tài)庫時(shí)程序運(yùn)行時(shí)加載的。但是動(dòng)態(tài)庫到底有什么作用,如何生成、如何加載等,我們卻很少關(guān)注。接下來,我給大家做一個(gè)簡單的介紹。1.1 動(dòng)態(tài)庫和靜態(tài)庫的區(qū)別靜態(tài)庫特點(diǎn)(linux):命名上是以 *.o 結(jié)尾靜態(tài)庫在鏈接階段直接就加入到可執(zhí)行的文件中了,在執(zhí)行過程中無需該靜態(tài)庫相對(duì)于動(dòng)態(tài)庫生成的文件,使用靜態(tài)庫生...https://blog.csdn.net/xiaoxiongxiongshi/article/details/104520188直接編譯進(jìn)進(jìn)程里頭:用JIT即時(shí)編譯器,直接編譯到進(jìn)程里頭。

27.AOT和JIT的區(qū)別是什么?

目前,程序主要有兩種運(yùn)行方式:靜態(tài)編譯與動(dòng)態(tài)解釋。

  • 靜態(tài)編譯的程序在執(zhí)行前全部被翻譯為機(jī)器碼,通常將這種類型稱為AOT (Ahead of time)即 “提前編譯”,典型代表是用C/C++開發(fā)的應(yīng)用,它們必須在執(zhí)行前編譯成機(jī)器碼
  • 而解釋執(zhí)行的則是一句一句邊翻譯邊運(yùn)行,通常將這種類型稱為JIT(Just-in-time)即“即時(shí)編譯”,代表則非常多,如JavaScript、python

IOS不讓JIT,所以不能直接熱更DLL,所以得使用Mono.Cecil庫對(duì)當(dāng)前工程下的Assembly-CSharp.dll程序集進(jìn)行IL注入。該中間代碼IL再經(jīng).NET平臺(tái)中的CLR(類似于JVM)編譯成機(jī)器碼讓CPU執(zhí)行相關(guān)指令。

28.Assembly-CSharp.dll程序集是什么?

項(xiàng)目中的cs代碼在打包時(shí)都會(huì)被打進(jìn)Assembly-CSharp.dll中,通過Mono調(diào)用。

29.Mono.Cecil庫干嘛的?

Mono.Cecil:一個(gè)可加載并瀏覽現(xiàn)有程序集并進(jìn)行動(dòng)態(tài)修改并保存的.NET框架

30 IL是什么?

IL的全稱是Intermediate Language (IL)即將.NET代碼轉(zhuǎn)化為機(jī)器語言的一個(gè)中間語言的縮寫。在一定程度上,我們可以將其理解為偽匯編語言。我們?cè)谑褂?NET框架中的C#、VB.NET、F#等語言的時(shí)候,編譯過程并不是像C/C++一樣直接編譯出原生代碼,而是編譯成IL中間語言。通過IL中間語言這種方式,可以實(shí)現(xiàn)跨平臺(tái)、提高程序靈活性等多種優(yōu)點(diǎn)。

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

?31.CLR是什么,JVM又是什么?

公共語言運(yùn)行庫 (common language runtime,CLR) 是托管代碼執(zhí)行核心中的引擎。運(yùn)行庫為托管代碼提供各種服務(wù),如跨語言集成、代碼訪問安全性、對(duì)象生存期管理、調(diào)試和分析支持。它是整個(gè).NET框架的核心,它為.NET應(yīng)用程序提供了一個(gè)托管的代碼執(zhí)行環(huán)境。它實(shí)際上是駐留在內(nèi)存里的一段代理代碼,負(fù)責(zé)應(yīng)用程序在整個(gè)執(zhí)行期間的代碼管理工作。

公共語言運(yùn)行庫_百度百科公共語言運(yùn)行庫 (common language runtime,CLR) 是托管代碼執(zhí)行核心中的引擎。運(yùn)行庫為托管代碼提供各種服務(wù),如跨語言集成、代碼訪問安全性、對(duì)象生存期管理、調(diào)試和分析支持。它是整個(gè).NET框架的核心,它為.NET應(yīng)用程序提供了一個(gè)托管的代碼執(zhí)行環(huán)境。它實(shí)際上是駐留在內(nèi)存里的一段代理代碼,負(fù)責(zé)應(yīng)用程序在整個(gè)執(zhí)行期間的代碼管理工作。https://baike.baidu.com/item/%E5%85%AC%E5%85%B1%E8%AF%AD%E8%A8%80%E8%BF%90%E8%A1%8C%E5%BA%93/2882128?fromtitle=CLR&fromid=10567215&fr=aladdinJVM是Java Virtual Machine(Java虛擬機(jī))的縮寫。

5.ILRuntime源碼實(shí)現(xiàn)

5.1 ILRuntime的原理

Runtime運(yùn)行時(shí)刻是指一個(gè)程序在運(yùn)行(cc或者在被執(zhí)行)的狀態(tài))

ILRuntime借助Mono.Cecil庫來讀取DLL的PE信息(Mono.Cecil庫也可以進(jìn)行IL注入),以及當(dāng)中類型的所有信息,最終得到方法的IL匯編碼,然后通過內(nèi)置的IL解譯執(zhí)行虛擬機(jī)來執(zhí)行DLL中的代碼。

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

?ILRuntime熱更流程:

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

ILRuntime的主要限制

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

6.熱更新的關(guān)鍵點(diǎn),重要節(jié)點(diǎn),疑難雜癥場(chǎng)景

6.1 為什么Xlua性能更差?

lua調(diào)CS代碼,還需要把XXXWrap.cs中的代碼往lua堆棧里面?zhèn)髦?,如果unity調(diào)用原生接口,就沒有這個(gè)步驟了。

6.2 Xlua的幾個(gè)優(yōu)勢(shì)

1.用的人最多,性能最好的lua熱更新插件對(duì)應(yīng)的熱更新解決方案。

2.xLua是騰訊開源的熱更新插件,有大廠背書和專職人員維護(hù),插件的穩(wěn)定性和可持續(xù)性較強(qiáng)

6.3?Net 4.6編譯的DLL啥意思?

如何編譯生成dll_李青鋒的專欄-CSDN博客_編譯dll動(dòng)態(tài)鏈接庫是Windows的基石。所有的Win32?API函數(shù)都包含在DLL中。3個(gè)最重要的DLL是KERNEL32.DLL,它由管理內(nèi)存、進(jìn)程和線程的函數(shù)組成;USER32.DLL,它由執(zhí)行用戶界面的任務(wù)(如創(chuàng)建窗口和發(fā)送消息)的函數(shù)組成;GDI32.DLL,它由繪圖和顯示文本的函數(shù)組成。在此,我們主要用實(shí)際的操作過程,簡要的說明如何創(chuàng)建自己的?Win32?DLL。一、創(chuàng)建DLL工程https://blog.csdn.net/qianchenglenger/article/details/21599235

6.4?CLR綁定使跨域調(diào)用是啥?

這里特指的是ILRuntime方案里面的主dll和熱更dll中間的跨域調(diào)用問題。

Unity C#熱更新方案 ILRuntime學(xué)習(xí)筆記(二) 代碼跨域調(diào)用https://segmentfault.com/a/1190000023290547

6.5 跨域繼承是啥?

同上的答案。

6.6?IL運(yùn)行時(shí)是啥?

Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)

6.7 不支持JIT的硬件環(huán)境(如iOS),為什么IOS不支持JIT ?

IOS不讓JIT,所以不能直接熱更DLL,所以得使用Mono.Cecil庫對(duì)當(dāng)前工程下的Assembly-CSharp.dll程序集進(jìn)行IL注入。該中間代碼IL再經(jīng).NET平臺(tái)中的CLR(類似于JVM)編譯成機(jī)器碼讓CPU執(zhí)行相關(guān)指令。

?為什么IOS不支持JIT,我也不知道。不過最新的IOS14.2又支持JIT模式了,難不成?以后基于DLL的熱更....又能用啦?那Xlua豈不是要被淘汰了?

6.8? 我的DLL怎么才能獲取到UnityEngine命名空間類的引用?

unity 使用C#反射獲取dll中的類、調(diào)用類中的字段、方法_被代碼折磨的狗子的博客-CSDN博客_c#獲取dll中的方法一、什么是反射?反射是.NET中的重要機(jī)制,通過反射,可以在運(yùn)行時(shí)獲得程序或程序集中每一個(gè)類型(包括類、結(jié)構(gòu)、委托、接口和枚舉等)的成員和成員的信息。有了反射,即可對(duì)每一個(gè)類型了如指掌。另外我還可以直接創(chuàng)建對(duì)象,即使這個(gè)對(duì)象的類型在編譯時(shí)還不知道。二、反射的使用平時(shí)我們的寫法是先引用命名空間(dll),然后new一個(gè)對(duì)象,通過這個(gè)對(duì)象調(diào)用其中的字段或方法,通過反射,我們可以不用添加dll來實(shí)現(xiàn)效果。1.首先我們?cè)贑#中創(chuàng)建一個(gè)Testdll類 打包dll,內(nèi)容如下using Sy.https://blog.csdn.net/qq_42345116/article/details/121695595反射assembly-csharp.dll中的類。

6.9 我的DLL需要如何打成AssetBundle?

資源怎么打包,它就怎么打包。

6.10 程序下載AssetBundle如何讀取里面DLL?

調(diào)JIT相應(yīng)的方法。反射熱更下來的 .dll中的類。

6.11如何測(cè)試各個(gè)熱更新方案的性能

Unity Profiler性能分析全解析_Tokyo_2024的博客-CSDN博客_unityprofilerProfiler概述打開Unity Profiler1. Window->Analysis->Profiler。https://blog.csdn.net/Tokyo_2024/article/details/105388523

6.參考資料

xlua擴(kuò)展第三方庫記錄_流彩飛霞的專欄-CSDN博客_xlua 第三方

如何評(píng)價(jià)騰訊在Unity下的xLua(開源)熱更方案?

Unity 游戲用XLua的HotFix實(shí)現(xiàn)熱更原理揭秘

騰訊開源手游熱更新方案,Unity3D下的Lua編程

[Unity]基于IL代碼注入的Lua補(bǔ)丁方案

另類Unity熱更新大法:代碼注入式補(bǔ)丁熱更新

unity dll實(shí)現(xiàn)熱更新_baidu_28955655的博客-CSDN博客_unity 熱更新

ILRuntime的實(shí)現(xiàn)原理 — ILRuntime

深入理解xLua熱更新原理 - 鋼與鐵 - 博客園文章來源地址http://www.zghlxwxcb.cn/news/detail-406125.html

到了這里,關(guān)于Unity中的熱更新的基礎(chǔ)知識(shí),Xlua與ILRuntime基礎(chǔ)知識(shí)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Unity 熱更新方案之——ILRuntime

    做游戲離不開熱更新,目前市面上熱更新方案用的比較多的是Lua(XLua,ToLua),最近又出現(xiàn)了基于C#的熱更新 huatuo(已改名HybridCLR又叫wolong)。來不及學(xué)習(xí)了,以后用到了再去了解吧。 筆者入行做的第一個(gè)項(xiàng)目是利用ILRuntime進(jìn)行熱更新的,當(dāng)時(shí)也是用的稀里糊涂的,一些坑點(diǎn)

    2023年04月08日
    瀏覽(15)
  • 【GAN】基礎(chǔ)知識(shí)(還在更新)

    【GAN】基礎(chǔ)知識(shí)(還在更新)

    還沒寫完,別罵了.....遇到啥新東西也會(huì)補(bǔ)充進(jìn)來 用來衡量分布之間距離 1.1.1 推導(dǎo)過程 如果想要對(duì)KL散度有一個(gè)比較好的理解,我其實(shí)建議看一下,從信息熵的角度入手我認(rèn)為是一個(gè)比較好的切入點(diǎn)?相對(duì)熵(KL散度)、JS散度和Wasserstein距離 ?和都是概率分布,一般代表真實(shí)

    2024年02月16日
    瀏覽(41)
  • MAUI學(xué)習(xí)之始--基礎(chǔ)知識(shí)(隨時(shí)更新)

    我理解的lambda表達(dá)式就是把函數(shù)名省略了一下 比如 1. 文本修飾:TexDecrations = \\\"\\\" // 可以加下劃線或者刪除線(就是字上劃一橫) 2. 轉(zhuǎn)換字體:CharacterSpacing = \\\"\\\" //字符間距,可以小數(shù),正數(shù)負(fù)數(shù) 3. 文本轉(zhuǎn)換:TextTransform=\\\"\\\" // 所有字符轉(zhuǎn)換大寫或小寫 4. 換行: 在Text=”“中,#

    2024年02月11日
    瀏覽(18)
  • 【Unity】xLua及熱更新

    【Unity】xLua及熱更新

    ????????本文主要講xLua的基本使用。看完有個(gè)基本認(rèn)識(shí)還是可以了,簡單的熱更操作還是可以做到的,但更多細(xì)節(jié)內(nèi)容依舊需要從官方文檔中了解、學(xué)習(xí)。 ????????xLua是由騰訊維護(hù)的一個(gè)開源項(xiàng)目,我們也可以將其看做一個(gè)插件。xLua為Unity、 .Net、 Mono等C#環(huán)境增加L

    2024年02月03日
    瀏覽(16)
  • Android Studio開發(fā)基礎(chǔ)知識(shí)(持續(xù)更新中~)

    閱讀本文需要有 Java 和 前端 的基礎(chǔ),本文是我學(xué)習(xí)Android時(shí)的筆記。 Info Key 復(fù)制行 Ctrl + D 刪除行 Ctrl + Y 注釋 Ctrl + / 注釋2 Ctrl + Shift + / 撤銷 Ctrl + Z 恢復(fù) Ctrl + Shift + Z 顯示結(jié)構(gòu) Ctrl + F12 格式化代碼 Ctrl + Alt + L 打開設(shè)置 Ctrl + Alt + S 自動(dòng)補(bǔ)全代碼 Ctrl + Shift + Space 自動(dòng)導(dǎo)包 Alt +

    2023年04月08日
    瀏覽(58)
  • unity打造基于xLua熱更新框架

    xLua是一款基于Lua的熱更新框架,它可以在游戲運(yùn)行時(shí)動(dòng)態(tài)加載Lua腳本,實(shí)現(xiàn)游戲邏輯的更新。在使用xLua框架之前,我們需要先了解一些基礎(chǔ)知識(shí)。 對(duì)啦!這里有個(gè)游戲開發(fā)交流小組里面聚集了一幫熱愛學(xué)習(xí)游戲的零基礎(chǔ)小白,也有一些正在從事游戲開發(fā)的技術(shù)大佬,歡迎你

    2024年02月16日
    瀏覽(18)
  • Unity面經(jīng)(自整)——Unity基礎(chǔ)知識(shí)

    Image比RawImage更耗性能。 Image只能使用sprite屬性的圖片。而RawImage什么都可以使用 碰撞器是觸發(fā)器的載體,而觸發(fā)器是碰撞器上的一個(gè)屬性。 如果IsTrigger為false,碰撞器根據(jù)物理引擎引發(fā)碰撞,產(chǎn)生碰撞的效果 如果IsTrigger為true,碰撞器被物理引擎忽略,沒有碰撞的效果 碰撞器

    2024年04月13日
    瀏覽(54)
  • Unity Xlua熱更新技術(shù)學(xué)習(xí)指南

    Unity Xlua熱更新技術(shù)學(xué)習(xí)指南

    熱更新是商業(yè)網(wǎng)絡(luò)游戲必不可少的一項(xiàng)技術(shù),而基于lua的熱更新技術(shù)又是Unity商業(yè)網(wǎng)游項(xiàng)目中的一個(gè)主流選擇。 部分同學(xué)近期表示自己在面試中被面試官提問熱更新相關(guān)知識(shí),但由于對(duì)熱更新能力有所缺失,最后遺憾的與心儀工作失之交臂。 由此可見,還是有一部分同學(xué)不了

    2024年04月23日
    瀏覽(24)
  • Unity | Shader基礎(chǔ)知識(shí)(第九集:shader常用單詞基礎(chǔ)知識(shí)速成)

    Unity | Shader基礎(chǔ)知識(shí)(第九集:shader常用單詞基礎(chǔ)知識(shí)速成)

    目錄 一、頂點(diǎn)(Vertex)和法線(Normal) 二、UV信息 三、 基礎(chǔ)數(shù)據(jù)種類 1 基礎(chǔ)數(shù)據(jù)種類 2 基礎(chǔ)數(shù)據(jù)數(shù)組 3 基礎(chǔ)數(shù)據(jù)數(shù)組的賦值 4 對(duì)數(shù)據(jù)數(shù)組的調(diào)用 四、 基礎(chǔ)矩陣 1 基礎(chǔ)矩陣種類 ?2?對(duì)矩陣數(shù)組的調(diào)用 2.1對(duì)一個(gè)數(shù)據(jù)的調(diào)用 ?2.2對(duì)多個(gè)數(shù)據(jù)的調(diào)用 ?2.3對(duì)數(shù)據(jù)的賦值 五、基礎(chǔ)紋理種

    2024年02月01日
    瀏覽(38)
  • XML的基礎(chǔ)知識(shí)及XMl文件的創(chuàng)建/讀取/更新demo詳解

    1.什么是xml? Xml(Extensible Markup Language),可擴(kuò)展標(biāo)記語言,一種用于存儲(chǔ)數(shù)據(jù)或傳輸數(shù)據(jù)的標(biāo)記語言,由萬維網(wǎng)(W3C開發(fā))。它允許開發(fā)人員創(chuàng)建自己的標(biāo)記,且簡單易讀,易擴(kuò)展,支持標(biāo)準(zhǔn)的字符編碼,如UFT-8,UTF-16. 2. Xml文檔的基本結(jié)構(gòu) 2.1文檔聲明 ,包括文檔版本(ver

    2024年04月09日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包