L#腳本語言,直接把DLL當腳本執行(圖解說明)


L#是什么:Run DLL as a Script.

A Pure C# IL Runner,直接解析執行IL的腳本引擎。

從原理上講是模擬執行了CLR的工作,從表現上講就是把DLL作為資源直接加載執行。

是不是很多同學夢寐以求的熱更DLL能熱更,但不是你想的那個熱更。

直接以反射符號的方式加載DLLDLL的解釋執行還是由CLR完成的。還會涉及JIT引擎。
但是L#"模擬"CLR的工作。不使用反射加載符號,不使用JIT
IOSUnity)、WP8這樣的平台,CLR就沒反射加載符號這樣的功能。IOS還關閉了JIT
L#
不受這個制約

但是就帶來了其他制約:交互上的一些麻煩

主要記住這一條:L#加載的DLL中的代碼屬於腳本代碼,和系統代碼中的程序不能互相繼承

L#的語法是什么樣的:

L# 是直接運行dotnet 的DLL, 你可以用c# vb.net f# 等。只要能通過編譯。
與C#Light自己實現語法解釋問題不同,L#沒有語法解釋層面的bug,只會有執行層面的bug。
恰恰是C#Light在語法解釋器的維護上陷入泥潭以后,深刻反思,才有了L#這個創意。

關於代碼:

可以在http://svn.cltri.com 取得最新代碼
或者https://github.com/lightszero/lsharp
目前還處於Alpha階段,Bug是少不了的,這個階段僅建議動手能力比較強的同學試用。
發現BUG罵我是肯定要罵的,如果罵完之后,能夠在Github上推一個錯誤用例
將不甚感激。

 

下面介紹一下L#在Unity3D的使用辦法

一步一步是這樣,是魔鬼的步伐

L#ForUnity3D Hell#oworld環境建立圖解

1.創建新項目

2.Copy L#forU3D的類庫到DLL中

或者直接插入L#forU3D的源碼也可以,自選

3.創建一個代碼供L#模塊訪問)

剽竊了龐麥郎的歌詞,但我是不會道歉的

4.創建一個L#模塊

5.添加L#模塊的引用

因為我們剛才在plugins目錄下創建的代碼Interface.cs,希望L#模塊訪問他,就對應Assembly-Csharp-firstpass這個模塊

6.編寫L#模塊

可以看到L#模塊粗獷的調用了我們的程序

然后F7,你會得到L#模塊的dll文件

7.把模塊文件作為資源放進Unity3D

把模塊文件改名為

HotFixCode.Dll.bytes

HotFixCode.Pdb.bytes

pdb這個文件不是必須的,但是當腳本出異常,你需要查一下是哪個文件哪一行出錯的時候,沒有pdb是查不出來的。只能給你一個干巴巴的地址。

當然你熟悉IL的話,自己用別的工具,根據這個地址也是可以找到代碼位置的。

他在Unity里面應該被識別為兩個TextAsset

8.編寫測試程序Test001

新建場景並保存Test001,

新建Test001腳本直接掛接到攝像機上

編寫代碼如下:

using UnityEngine;

using System.Collections;

 

public class test001 : MonoBehaviour {

 

    CLRSharp.CLRSharp_Environment env ;

    // Use this for initialization

    void Start () {

        //創建CLRSharp環境

        env=new CLRSharp.CLRSharp_Environment(new Logger());

    }

    

    // Update is called once per frame

    void Update () {

    

    }

    public class Logger:CLRSharp.ICLRSharp_Logger//實現L#的LOG接口

    {

        public void Log (string str)

        {

            Debug.Log (str);

        }

        

        public void Log_Error (string str)

        {

            Debug.LogError (str);

        }

        

        public void Log_Warning (string str)

        {

            Debug.LogWarning (str);

        }

    }

}

9.執行HelloWorld

進入Unity,運行項目

這是唯一的結果,有一條Log L#被初始化了

L#HelloWorld 第二步,調用L#模塊圖解

繼續增加代碼

 

在Start函數后增加代碼

0.加載模塊

        //加載L#模塊
        TextAsset dll = Resources.Load("HoxFixCode.dll") as TextAsset;
        TextAsset pdb = Resources.Load("HoxFixCode.pdb") as TextAsset;
        System.IO.MemoryStream msDll = new System.IO.MemoryStream (dll.bytes);
        System.IO.MemoryStream msPdb = new System.IO.MemoryStream (pdb.bytes);
        //env.LoadModule (msDll, null);//不需要pdb的話,第二個參數傳null
        env.LoadModule (msDll, msPdb);

1.創建線程上下文

2.取得准備調用的類型

3.調用靜態函數

4.調用成員函數

完整的start函數代碼

    void Start () {

        //創建CLRSharp環境

        env=new CLRSharp.CLRSharp_Environment(new Logger());

 

        //加載L#模塊

        TextAsset dll = Resources.Load("HoxFixCode.dll") as TextAsset;

        TextAsset pdb = Resources.Load("HoxFixCode.pdb") as TextAsset;

        System.IO.MemoryStream msDll = new System.IO.MemoryStream (dll.bytes);

        System.IO.MemoryStream msPdb = new System.IO.MemoryStream (pdb.bytes);

        //env.LoadModule (msDll, null);//不需要pdb的話,第二個參數傳null

        env.LoadModule (msDll, msPdb);

        Debug.Log ("LoadModule HotFixCode.dll done.");

 

        //step01建立一個線程上下文,用來模擬L#的線程模型,每個線程創建一個即可。

        CLRSharp.ThreadContext context = new CLRSharp.ThreadContext (env);

        Debug.Log ("Create ThreadContext for L#.");

 

        //step02取得想要調用的L#類型

        CLRSharp.ICLRType wantType = env.GetType ("HoxFixCode.TestClass",null);//用全名稱,包括命名空間

        Debug.Log ("GetType:"+wantType.Name);

        //和反射代碼中的Type.GetType相對應

 

        //step03 靜態調用

        //得到類型上的一個函數,第一個參數是函數名字,第二個參數是函數的參數表,這是一個沒有參數的函數

        CLRSharp.IMethod method01 = wantType.GetMethod("Test1",CLRSharp.MethodParamList.MakeEmpty());

        method01.Invoke (context, null, null);//第三個參數是object[] 參數表,這個例子不需要參數

        //這是個靜態函數調用,對應到代碼他就是HotFixCode.TestClass.Test1();

 

        //step04 成員調用

        //第二個測試程序是一個成員變量,所以先要創建實例

        CLRSharp.CLRSharp_Instance typeObj = new CLRSharp.CLRSharp_Instance (wantType as CLRSharp.ICLRType_Sharp);//創建實例

        CLRSharp.IMethod methodctor = wantType.GetMethod(".ctor",CLRSharp.MethodParamList.MakeEmpty());//取得構造函數

        methodctor.Invoke (context, typeObj, null);//執行構造函數

        //這幾行的作用對應到代碼就約等於 HotFixCode.TestClass typeObj =new HotFixCode.TestClass();

        CLRSharp.IMethod method02 = wantType.GetMethod("Test2",CLRSharp.MethodParamList.MakeEmpty());

        method02.Invoke (context, typeObj, null);

        //這兩行的作用就相當於 typeOBj.Test2();

    }

執行結果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM