L#脚本语言,直接把DLL当脚本执行(图解说明)

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

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

从原理上讲是模拟执行了CLR的工作,从表现上讲就是把DLL作为资源直接加载执行。

是不是很多同学梦寐以求的热更DLL不是。

直接以反射符号的方式加载DLL,DLL的解释执行还是由CLR完成的。还会涉及JIT引擎。
但是L#是"模拟"CLR的工作。不使用反射加载符号,不使用JIT
在IOS(Unity)、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();

????}

执行结果

时间: 2024-10-13 21:57:40

L#脚本语言,直接把DLL当脚本执行(图解说明)的相关文章

如何在Java平台上使用脚本语言做Java开发

如何在Java平台上使用脚本语言做Java开发     最近开始流行区分Java平台和Java语言,但很多Java开发者还是不能确定如何在 Java应用程序开发中结合脚本.本篇文章,Gregor Roth给出了在Java平台上使用脚本的方法.通过这篇文章,你可以了解怎样在你的Java应用程序中使用脚本,是否你要通过使用Groovy和 Jython把不同的Java应用程序模块粘合在一起,或者写一个你自己的基于JRuby的应用程序,适用于Java平台. 作为一个Java开发者,你可能已经注意到了,J

哪种脚本语言最适合你!

本文译自 iSystemAdmin 的 <List Of Popular Scripting Languages for Linux and Windows>. 具备脚本知识的系统管理员与其他系统管理员有着明显的区别.脚本是一门“系统管理员”创造的艺术.这门艺术需要了解系统本身的相关知识,系统管理命令的语法,编程和算法知识以及至少一门脚本编程语言.对系统管理员来说编写脚本有很多选择,每种脚本语言都有着自己独特的语法和优点.脚本语言之间几乎没有相似之处,但也不会像外星语那样难以读懂.脚本语言既可

Linux和Windows脚本语言

本文译自 iSystemAdmin 的 <List Of Popular Scripting Languages for Linux and Windows>. 具备脚本知识的系统管理员与其他系统管理员有着明显的区别.脚本是一门“系统管理员”创造的艺术.这门艺术需要了解系统本身的相关知识,系统管理命令的语法,编程和算法知识以及至少一门脚本编程语言.对系统管理员来说编写脚本有很多选择,每种脚本语言都有着自己独特的语法和优点.脚本语言之间几乎没有相似之处,但也不会像外星语那样难以读懂.脚本语言既可

脚本语言与编译型语言

不同 编译型语言: 编译型程序所生成的指令时二进制形式的机器码和操作数, 就是所谓的二进制流, 二进制程序是CPU可以直接识别执行的 解释性语言: 脚本语言的解释器是二进制形式的, 可以被CPU直接识别的, 但是脚本解释器的输入是脚本语言字符串, CPU执行脚本语言解释器, 而脚本语言解释器去执行脚本语言, 中间隔了一层, 脚本程序是通过CPU间接运行的 脚本语言的两大类: 一边解释一边执行-->所以不会有opcode生成 分析整个文件后创建抽象语法树生成opcode, 有了指令之后让解释器去执

脚本语言的分类

分类(脚本语言分类的标准是脚本语言的语法风格) 基于命令的 --> 类似于汇编语言, 一行代码有操作码和参数组成, 所以不支持循环 基于规则 面向过程 面向对象: smalltalk是世界上第一个纯正的面向对象语言 原文地址:https://www.cnblogs.com/megachen/p/9775795.html

高质量编码--易变业务使用脚本语言编写

本文是阅读了<编写高质量代码 改善Java程序的151个建议>后学习理解后进行的产出,同样是为了方便我后面的回顾. 废话不多说,开始. 脚本语言是在运行期解释执行的,这种特性正是Java所缺少的,java是一种编译解释的语言,在进行修改后,就需要重新编译,才能实现修改的内容. 脚本语言的优点:灵活,便捷,简单.通过引入脚本语言可以使Java更加强大. 先上代码 import javax.script.Bindings; import javax.script.Invocable; import

在C++代码中调用L脚本语言

L脚本语言同意被其他编程语言调用.如C++,非常easy.仅仅要在宿主语言中载入L脚本引擎的动态库 直接调用这两个函数就能够了 extern "C" int __stdcall ScriptEngineDoString(wchar_t * ScriptString); extern "C" int __stdcall ScriptEngineDoScriptFile(wchar_t * ScriptFileName); C语言调用L脚本引擎的样例: #include

L脚本语言调用操作系统API

L脚本语言支持直接调用操作系统提供的C语言API函数,以保证供更大程度的灵活性 目前,仅支持函数调用约定为__stdcall 的C语言函数 C语言的变量和L脚本语言的对象不是一一对应的关系,因此调用C语言函数的时候不能直接将L脚本语言的对象作为参数传入,但是可以进行适当的转换 下面是一个调用windows系统kernel32.dll中OutputDebugStringW函数和 一个调用user32.dll 中MessageBoxW函数的例子 并将其封装为L脚本语言的全局函数 #scplib 定义

L脚本语言语法手册 0.10版

L脚本语言语法手册 0.10版 赵亮       简  介 L脚本语言是一个轻量级的,旨在接近自然语言的编程语言,目前支持在中文.英文基础上的编程.并可扩展为任意语种.L脚本语言的语法结构简单,程序结构相对松散,易学易用. 目前L脚本语言仍处于开发初期,功能尚不完善.目前提供了一个简单的源码编辑器,建议使用notepad++或者ultraedit进行源码编辑. 目录 一.        介绍.. 2 二.        注释.. 3 三.        对象定义和引用.. 3 四.