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 ...
随机推荐
- 122. Best Time to Buy and Sell Stock(二) leetcode解题笔记
122. Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price ...
- SDN三种模型解析
数十年前,计算机科学家兼网络作家Andrew S. Tanenbaum讽刺标准过多难以选择,当然现在也是如此,比如软件定义网络模型的数量也很多.但是在考虑部署软件定义网络(SDN)或者试点之前,首先需 ...
- 下载Orchard源码
下载地址:http://orchardproject.net/download
- AD帐户操作C#示例代码(二)——检查密码将过期的用户
本文接着和大家分享AD帐户操作,这次开发一个简单的检查密码将过期用户的小工具. 首先,新建一个用户实体类,属性是我们要取的用户信息. public class UserInfo { /// <s ...
- 论ubuntu的作死技巧
此处记录自己弄崩系统的几大杀器,长期更新. 1. sudo apt-get autoremove
- 使用xtrabackup备份mysql数据库
数据在一个企业里非常重要,因此经常需要备份数据库,确保出线故障时,可以立刻恢复数据到最新状态,目前常见的备份工具有mysqldump和xtrabackup,数据量较少时可以使用mysqldump,但随 ...
- Mac OS X 访问 Windows 共享文件夹
Mac OS X 访问 Windows 共享文件夹 mac没有网络邻居,但可以使用finder访问局域网中windows共享的文件 1.点击 Finder 前往菜单中的「前往服务器」(或快捷键 com ...
- 使用Prism6 建立 Windows 10 通用程序.
使用Prism6 建立 Windows 10 通用程序. 目标: 使用prism6,建立Windows 通用程序项目. 1, 解决方案—添加新建项目—通用—空白应用—输入名称—确定—确定 2 ,引用上 ...
- To Use FTP Command in Linux
Yesterday I was asked to upload a file in Linux to the corresponding server. I said "oops" ...
- Xml生成节点声明
XmlDocument xmlDoc = new XmlDocument(); XmlDeclaration declaration = xmlDoc.CreateXmlDeclaration(&qu ...