開發(fā)概覽:非托管插件開發(fā)(Native/Unmanaged Plugin)
時(shí)間:2022-04-28 21:03:01 | 來源:行業(yè)動態(tài)
時(shí)間:2022-04-28 21:03:01 來源:行業(yè)動態(tài)
Unity是基于Microsoft .Net Framework開發(fā)的游戲引擎2,它采用了開源的.NET Platform,并依賴此框架來實(shí)現(xiàn)跨硬件設(shè)備和運(yùn)行時(shí)(操作系統(tǒng))的目標(biāo),也是所謂的Write once, run anywhere。在語言方面,Unity選擇C#作為主要的腳本編程語言,雖然.NET平臺本身支持的語言有很多種。
進(jìn)一步,Unity支持Mono和ILC2PP兩種腳本框架(Scripting Backends)。特別的,Unity Editor采用的是Mono腳本框架。
一般的,游戲類庫開發(fā)者可以選擇直接用C#語言開發(fā),目標(biāo)類庫可以實(shí)現(xiàn)基于.NET Framework基礎(chǔ)功能之上的高級功能,這類插件稱之為Managed Plugin(托管插件)。由于環(huán)信IM核心SDK已經(jīng)基于C 開發(fā),因此我們選擇另一種Native Plugin(本地插件)的方式,正是它把我們引向了迷宮之旅。兩種類型的Plugin介紹,參見3。
不幸的是,Unity網(wǎng)站上關(guān)于Native Plugin的相關(guān)介紹少只又少,想要了解它的具體細(xì)節(jié)還要去參考Microsoft MSDN文檔。作為中規(guī)中矩的文檔介紹,微軟的文檔是合格的,但是,當(dāng)你真正上手編程時(shí)就會發(fā)現(xiàn),這些遠(yuǎn)遠(yuǎn)不夠:下面記錄的一些坑點(diǎn)就很難在相應(yīng)的文檔中得到直接的提示;而要通過Google大法,結(jié)合其他程序員留下的蛛絲馬跡,再加上自己不斷的調(diào)試來最終確認(rèn)。
在微軟文檔上下文中,Unity Native Plugin有個(gè)另外的名字:Unmanaged Plugin,即非托管插件。簡單來講,Managed Plugin生存在.NET Framework的運(yùn)行時(shí)環(huán)境(類似于Java的JVM),而Unmanaged Plugin則生存在這個(gè)運(yùn)行時(shí)環(huán)境之外,也即和運(yùn)行時(shí)環(huán)境是兄弟的關(guān)系。如果你原本的類庫實(shí)現(xiàn)滿足微軟的COM(Component Object Model)規(guī)范,那自然最好是使用COM Interop4的互操作方式;而環(huán)信IM SDK本身是純C 實(shí)現(xiàn),因此采用了Platform Invoke5(簡稱P/Invoke)方式,本文剩下的內(nèi)容均是基于P/Invoke。
下圖則概要描述了Managed和Unmanaged區(qū)域代碼之間互相操作的方式:
更具體的,為了實(shí)現(xiàn)對于Unmanaged DLL function的調(diào)用,只需要簡單的4步6:
1、確認(rèn)DLL類庫中需要被操作的函數(shù);
2、創(chuàng)建一個(gè)C#類來關(guān)聯(lián)被操作的這些函數(shù)(給函數(shù)穿上一個(gè)馬甲,以便集中管理和反復(fù)調(diào)用);
3、使用DllImport標(biāo)志在受管側(cè)(C#)定義函數(shù)原型;
4、在受管側(cè)隨意調(diào)用相關(guān)非托管區(qū)域函數(shù)。
上圖中,Standard marshalling service即負(fù)責(zé)將數(shù)據(jù)在兩個(gè)區(qū)域進(jìn)行封裝/解封裝傳送(marshall/unmarshall),它主要定義了數(shù)據(jù)在兩個(gè)不同內(nèi)存區(qū)域進(jìn)行拷貝(Copy)和引用(Reference)的規(guī)則7,而迷宮中的坑主要是和這些具體規(guī)則有關(guān)。