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();
}
执行结果

L#脚本语言,直接把DLL当脚本执行(图解说明)的更多相关文章
- SWIG 3 中文手册——4. 脚本语言
目录 4 脚本语言 4.1 两种语言的概览 4.2 脚本语言如何调用 C? 4.2.1 包装器函数 4.2.2 变量链接 4.2.3 常量 4.2.4 结构体与类 4.2.5 代理类 4.3 构建脚本 ...
- [改善Java代码]易变业务使用脚本语言编写
建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...
- js脚本语言在页面上不执行
转换原理:// 编码原理就是创建TextNode节点,附加到容器中,再取容器的innerHTML.(将脚本编码) // 解码原理是将字符串赋給容器的innerHTML,再取innerText或text ...
- java 计算数学表达式及执行脚本语言
java SE6中对常用的脚本语言做了支持. 可供使用者在java代码中执行脚本语言,还可以利用get("key"),put("key","value ...
- 为什么叫Unity3d为脚本语言
初接触Unity,看到大家说的都是工作主要是写脚本语言. 一直纳闷为什么说脚本语言呢,c#可不是脚本语言啊. -- -- 后来释然,说它是脚本语言是因为传统程序都是由代码构成的(像iOS.Androi ...
- 脚本、脚本语言、shell脚本
脚本是批处理文件的延伸,是一种纯文本保存的程序,一般来说的计算机脚本程序是确定的一系列控制计算机进行运算操作动作的组合,在其中可以实现一定的逻辑分支等.脚本程序相对一般程序开发来说比较接近自然语言,可 ...
- 1.5 Linux中大量使用脚本语言,而不是C语言!
说到在 Linux 下的编程,很多人会想到用C语言,Linux 的内核.shell.基础命令程序,也的确是用C语言编写的,这首先证明了一点,C语言很强很通用. 到目前为止,C语言依然垄断着计算机工业中 ...
- L脚本语言语法手冊 0.10版
L脚本语言语法手冊 0.10版 简 介 L脚本语言是一个轻量级的,旨在接近自然语言的编程语言,眼下支持在中文.英文基础上的编程.并可扩展为随意语种.L脚本语言的语法结构简单.程序结构相对 ...
- 在C++代码中调用L脚本语言
L脚本语言同意被其他编程语言调用.如C++,非常easy.仅仅要在宿主语言中载入L脚本引擎的动态库 直接调用这两个函数就能够了 extern "C" int __stdcall S ...
随机推荐
- 树莓派安装Transmission-daemon出现的问题
1,安装时发现默认的源里面没有transmission-daemon包 pi@fynn:/etc/apt/sources.list.d $ sudo apt-get install transmiss ...
- 【Java】:压缩成多个压缩卷
Java自带的库不支持压缩成多个压缩卷,找到了一个开源库 zip4j ,发现更好用 so easy package com.jws.common.mail; import java.io.File; ...
- python基础第四天(1)
冒泡算法--算法 需求:请按照从小到大对列表 [13, 22, 6, 99, 11] 进行排序 思路:相邻两个值进行比较,将较大的值放在右侧,依次比较! 第一步 li = [13, 22, 6, 99 ...
- C语言通过timeval结构设置周期
在C语言中,我们经常需要设置一个时间周期.在这里,我们通过Timeval结构实现时间周期的设置.首先,我们介绍timeval,其定义如下(转载http://www.cnblogs.com/wainiw ...
- Linux的.a、.so和.o文件
在说明Linux的.a..so和.o文件关系之前,先来看看windows下obj,lib,dll,exe的关系 windows下obj,lib,dll,exe的关系 lib是和dll对应的.lib是静 ...
- 我与solr(二)--导入mysql数据库
关于solr的搭建详见上一篇的随笔. 步骤1: 在webapps中solrhome下新建一个文件夹名字叫做mynode(名字不固定,可以随便取,但是这个名字在后面的配置中会有所关联.)然后在mynod ...
- 用 R 进行高频金融数据分析简介
作者:李洪成 摘自:http://cos.name/wp-content/uploads/2013/11/ChinaR2013SH_Nov03_04_LiHongcheng.pdf 高频数据 金融市场 ...
- Tomcat部署遇到的问题
项目服务端:Tomcat6.0.41 选用数据库:Mysql5.6.17 JDK环境:1.6.37 运行系统:Windows server 2008(64bit) ================== ...
- ListView之头部浮动效果
ListView 中有时需要在顶部固定一个浮动栏,当向上滑动 ListView 时,浮动栏固定在顶部,当向下滑动 ListView 到其 HeaderView 可见时,浮动栏成为ListView的一部 ...
- P1905生活大爆炸版 石头剪刀布
P1905生活大爆炸版 石头剪刀布 描述 石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头.如果两个人出拳一 样,则不分胜负.在<生活大爆炸>第二季第 8 集中出现了一种石头 ...