aardio + .NET 快速开发独立 EXE 程序,可防 ILSpy 反编译
aardio可以非常方便地调用.NET(不需要任何复杂的步骤)。
.NET在aardio中很好用,系统自带.NET组件以及各种开源.NET组件在aardio用户中也很受欢迎。
aardio+.NET生成的EXE——可避免被ILSpy直接反编译。
aardio调用.NET示例:
//导入.NET支持库importdotNet;//导入.NET程序集("System");//调用类的静态成员函数varisValidHost=("");//构造.NET对象varuri=("");//读或写.Net对象的实例属性varhost=;//调用.Net对象实例的成员函数varhash=();aardio语法与JavaScript接近,请参考:aardio编程语言快速入门——语法速览
aardio+.Net开发对.NET版本没有严格要求——兼容流行Windows系统自带的不同版本.NET。不但可以调用系统自带的大量.NET组件,也可以生成体积很小的EXE文件。
内存加载.NET程序集,生成独立EXEaardio提供()函数——可以方便地通过内存数据加载.NET程序集,这样就可以生成独立EXE程序,不再需要带上一堆DLL文件。
将内存数据绑定为.NET程序集示例:
importdotNet;({[""]=34;\";});()的第1个参数指定程序集名称,第2个参数指定实际要加载的程序集路径或内存数据,aardio代码在文件路径前加$号可将文件数据编译为二进制字符串(发布后不再需要原文件)。
然后就可以正常导入内存程序集了,代码如下:
("");上面的代码导入.NET程序集,然后再将.NET名字空间导入aardio,()函数的作用与下面的代码相同:
//导入.NET程序集varassembly=("");//导入.NET名字空间("");aardio标准库提供的.NET库aardio标准库中已经提供了一些.NET库,例如System,调用示例:
//导入.NET名空间importSystem;//用System名字空间下面的类构造对象实例varuri=("")//读或写.Net对象的实例属性varhost=;aardio代码一般使用小驼峰命名风格,但.NET名字空间或类名一般会大写首字母以示区别。
可以看到这个Sytem库的关键代码只有两句:
importdotNet;("System")嵌入.NET窗口控件到aardio窗口aardio窗口嵌入.NETDataGridView控件范例的运行效果:
首先要了解.Net的所有控件都应当放在.Net创建的窗口里(也就是对象),窗口是管理控件的容器,不能直接把控件单独拧出来往aardio窗口里扔。
如果不想去弄个窗口,aardio提供了一个更简单的方法,例如把.Net的DataGridView控件直接嵌入aardio窗口:
;varForms=;vardataGridView=("DataGridView",);非常简单。
好了,现在创建DataTable数据表,准备把他显示到控件里,先创建数据列,重点看怎么指定列字段使用的数据类型:
//添加数据列vardataTable=("DT");("名称");//添加列("计数",(""));//添加指定数据类型的列("选择",(""));//自动显示复选框然后绑定数据源到视图:
//绑定数据源到视图vardataView=(dataTable);=dataView;=2;
好吧,想再加一个下拉框吗?!这个就略有些麻烦了,代码如下:
//先移除自动生成的列("名称");//下面添加下拉框以替换上面移除的列varcmbColumn=();=120;="Name";="名称";//对应上面dataTable里的字段名="名称";//显示在列标题里的文本//如果名称与显示值一样,那直接给赋值一个数组就可以//下面绑定下拉候选框的数据源,上面的DataPropertyName才是真正要读写的数据值。="Name";//下拉框显示文本的属性名="Value";//下拉框选项值的属性名=({"王五","张三"},{"WangWu","ZhangSan"});//添加这个新的下拉框到数据视图(cmbColumn);//移动到第一列["Name"].DisplayIndex=0;然后添加下面的代码响应.NET控件的事件:
//添加事件(event)=function(ser,eventArgs){varcolumnName=;varvalue=(columnName);("已改变列:",columnName,"已变更值:",value);}然后读写数据:
//添加测试数据varrow=();={"WangWu",123,true}(row);//读取数据=function(id,event){for(i=1;;1){vararr=[i].ItemArray;(arr[1]);}}以上完整范例源代码请参考aardio自带范例:
可以看到aardio自带了大量调用.NET的范例。
在aardio中加载的.NET程序集如何调试用下面的代码在aardio中加载.NET程序集的pdb调试文件:
("程序集路径","pdb调试文件路径");然后用VS附加运行的aardio进程就可以调试了,懂.NET的都懂,这个不多说了。
用aardio在运行时编译C语言编译器varcompiler=("C源码(注释可赋值为字符串,注释标记首尾星号数目要一致)=/***?/*如果C编写的类构造对象实例varnetObj=();//调用实时编译的C源码,这个字符串支持类似PHP的模板语法,所以我们可以用aardio代码灵活地在运行时生态生成比较复杂的C源码编译为内存程序集,这样很适合生成独立EXE文件。注意在aardio中编译C代码生成DLL程序集)。
.NET与aardio对象相互转换规则aardio会自动处理类型转换,调用.NET函数时如果参数类型不一致——aardio也会尽最大可能地转换参数类型,用起来还是比较轻松的。但简单了解一下类型转换规则和原理是有必要的。
所有原生.NET对象在aardio中分为两类:
1、可自动转换的简单值类型
null值、数值、字符串、枚举、等简单值类型,以及这些值类型的数组可以直接交换。aardio中的buffer在.NET中对应字节数组。
2、在aardio中存为COM对象的.NET对象
其他原生.NET对象在aardio存为对象(对应.NET中的System.__ComObject类型),其中有些特殊的.NET对象(例如struct,ValueTuple),在传入aardio时会封包为特殊的DispatchableObject对象。这些.NET对象在aardio中都会被封装为对象,在aardio中使用没有太大区别。
aardio与.NET交互基于COM接口,所以遵守aardio的COM传参基本规则:
.NET中的enum枚举会自动转换为aardio中的数值(双向自动转换),
.NET中的struct,tuple由.NET对象DispatchableObject封包后再返回aardio。
aardio函数则自动转换为委托、事件所需要的委托类型。
.NET中的,类型在aardio中会自动转换为整数值,
aardio中的指针类型(pointer)必须使用tonumber()函数转换为数值才能传入.NET。
窗口句柄(HWND)在aardio以整数值表示,可以直接传入.NET。
在aardio则会自动转换为ARGB格式的颜色数值。
调用.NET时ARGB格式的颜色数值也能自动转换为对象。
注意GDI+使用ARGB格式颜色值,与gdip库,plus控件等兼容。
aardio提供以下函数创建指定静态类型的对象:
以上函数会将参数1存为.NET对象并封包为DispatchableObject对象后再返回对象,(简单的值类型也会转换为对象),这可以让aardio直接引用.NET中的对象,方便实现ref,out等输出参数。
下面的aardio代码演示了的用法:
importdotNet;varcompiler=("C源代码=/***namespaceCSharpLibrary{publicclassObject{publicstaticvoidTest(refdoublenum,int[]arr){num=12.3;arr[0]=56;}}}***///编译程序集并导入名字空间("CSharpLibrary");//创建.Net对象,启用引用传参。varnum=(12.5,true);//创建.Net数组vararr=({1,2,3});//调用.NET函数。(num,arr);importconsole;/*对象如果存储的是数组,可用下标直接读写数组成员。*/(arr[1])/*对象如果存储的是Primitive,enum,string类型或这些类型的普通数组,则可使用Value属性读写原始值。*/();//支持tostring()转换为字符串,tonumber()转换为数值。(tostring(num),tonumber(num));();下标C");=/******usingSystem;;namespaceCSharpLibrary{publicclassTestClass{privateObject[]values=newObject[]{1,2,3,4,5,6,7,8,9};publicObjectthis[intindex]{get{returnvalues[index];}set{values[index]=value;}}publicDictionarystring,stringdict=newDictionarystring,string();}}******///编译并引入C编写的类构造对象实例varnetObj=();//读下标属性,按C规则)。
2、如果下标为数值可以省略Item直接写[],但这时要起始下标为1(遵守aardio规则)。
调用UWP用下面的aardio代码创建支持调用UWP组件的C源码=/******usingSystem;;;;;;;;;;;namespaceaardio{publicclassUwpOcrResult{publicUwpOcrResult(OcrResultocrRet){ocrResult=ocrRet;}publicintLineCount(){;}publicstring[]GetWords(intindex){ArrayListarr=newArrayList();foreach([index].Words){();}return(string[])(typeof(string));}publicobjectGetWordRects(intindex){ArrayListarr=newArrayList();foreach([index].Words){double[]rc={,,,};(rc);}return(object)(typeof(object));}privateOcrResultocrResult;}publicclassUwpOcrEngine{publicstring[]AvailableRecognizerLanguages(){ArrayListarr=newArrayList();foreach(){();}return(string[])(typeof(string));}publicobjectIsLanguageSupported(stringname){=(name);(lang);}publicUwpOcrResultRecognize(byte[]imgBuffer,stringlanguage){returnnewUwpOcrResult(RecognizeAsync(imgBuffer,language).GetAwaiter().GetResult());}asyncTaskOcrResultRecognizeAsync(byte[]imgBuffer,stringlanguage){varrandomAccessStream=newInMemoryRandomAccessStream();varoutputStream=(0);vardw=newDataWriter(outputStream);vartask=newTask(()=(imgBuffer));();awaittask;();();BitmapDecoderdecoder=(randomAccessStream);SoftwareBitmapsoftwareBitmap=(,);=(language);OcrEngineengine=(lang);if(engine!=null){OcrResultocrResult=(softwareBitmap);returnocrResult;}returnnull;}}}******///编译并返回程序集varassembly=();importconsole;if(assembly)("编译成功",);
支持库的体积很小,可以生成独立EXE文件,调用代码也非常简洁。下面是调用示例:
更多






