本帖最后由 jacenhe 于 2022-4-23 13:17 编辑
“COM 接口慢,甚至是调用 COM 接口的语言慢”—— 这个说法是不准确的。
COM 并不慢,只不过 AutoCAD 是进程外调用,相对进程内调用当然会有一点成本。
瞬间大量调用外部接口,这肯定会把微小的速度差异放大,但实际程序开发中一般没必要这样做,或者有其他方法避免。
跨进程调用在现代软件开发中其实很常用,不是非常夸张地密集调用对运行速度的影响一般可以忽略不计。
调用服务端 API 敢就更是跨过千山万水去调用了,相比进程间通信来说就更慢了,但这并不妨碍现代软件大量使用远程接口。
首先如果我们用 aardio 开发一个软件,至少图形界面这部分根本不需要与 AutoCAD 交互,也肯定存在大量不需要与 AutoCAD 直接交互的功能函数。
通过 COM 接口也可以调用 AutoCAD 执行 LISP ,而且与 LISP 交互并不一定非要通过 COM 接口,也可以使用其他编程语言动态生成 LISP 代码然后再执行。通过 COM 接口也可以调用 AutoCAD 加载 .Net 编写的 DLL,我在 aardio 里就提供了一个例子,在 aardio 里直接编译 C# 代码生成 DLL 程序集,然后再通过 COM 接口 cad.NetLoad() 加载 .Net 写的 DLL,再通过 cad.SendCommand() 就可以调用该 DLL。
参考:aardio 范例 / COM 组件 / AutoCAD
所以通过 COM 接口调用 AutoCAD 并不会丢失 LISP / .Net 的优势,而是在这个优势的基础上叠加了其他编程语言以及 COM 接口的优势。 我们使用任何一种技术,都是为了善用他的优势、扬长避短。
至于 aardio 与其他编程语言交互是非常方便的,
以 Python 为例,Google 一下 "aardio + Python " 可以找到很多 Python 用户分享的愉快体验。这是前几天一个 Python 用户给我的留言:
感谢aardio作者,我是刚开始用aardio写界面(实在不想用pyqt了),python写数据处理业务,感受到了aardio的强大和奇妙。我想把python数据处理过程的信息反馈到前端界面中,《这回让我们把 Python 玩出花来》看完后,用了几分钟搞定!!!实在令人惊讶aardio的强大!!!再次感谢aardio作者的奉献!!!
aardio 支持非常多的第三方编程语言,目前可以支持C语言、C++、C#、Java、Python、R、Javascript、Node.Js、Fortran、VB、Flash ActionScript、PHP、VBScript、PowerShell、NewLISP、AutoLISP、Delphi、FreeBASIC、Ruby、Rust、Julia、Nim、Go 语言、批处理 ...... 并且仍在继续增加中。说 aardio 资料少是一个误解,aardio 的资料不但非常多,而且可以直接利用大量第三方编程语言的资源。
aardio 语法接近 Javascript ,不需要过多的学习成本,历经 17年 活跃更新已经成熟且稳定。
而且 aardio 非常小,开发环境仅 6.5 MB(包含开源的标准库、范例文档、开发环境),下载就可以使用,不需要任何复杂的配置。
曾经有知名博主针对某个 aardio 编写的开源软件 —— 与一系列其他语言编写的同类软件试用评测对比后得出的总结是:aardio 编写的软件运行最流畅,使用体验吊打同类软件,并且非常稳定从未遇到报错,而这个 aardio 软件只用了非常少的代码 —— 体积不到同类软件的十分之一,而其他用各种桌面开发工具开发的同类软件,不但界面不顺畅,各种恼人的 BUG 也非常多。所以 aardio 编写的桌面软件拥有良好的可靠性。
我们先看一些 aardio 编写的开源软件:
最近很受欢迎的开源录屏软件 Gif123 就是用 aardio 写的,体积仅 820 KB,无任休何外部依赖,单文件绿色软件,兼容 XP,Vista,Win7,Win8,Win10,Win11 …… 等所有流行桌面操作系统。
开源项目 WubiLex,仅积仅 890KB,同样是单文件绿色软件。百度贴吧一个关于 WubiLex 的讨论帖子已经超过 1200 回复,WIN10系统自带五笔的码表与短语词库安装、管理工具,并可增强微软五笔的设置、热键等功能。只要一个EXE文件,不需要安装,不需要任何DLL依赖。软件已自带五笔86、98、091、新世纪码表,以及极点五笔、QQ五笔、微软五笔默认词库、昱琼词库、海峰词库等。甚至自带了郑码词库、可以一键把微软五笔替换为郑码输入法
开源项目 WinAsar,体积仅 500KB,单文件,不需要运行时,支持所有 Windows 操作系统,Electron asar 文件打包、解包工具,不需要安装 Node.js,纯 aardio 代码实现的 asar 解析器。
下面这个是 8 年前 aardio 写的开源项目,作者仅临时学了个把月 aardio
类似的还有很多,就不再截图了。
aardio 编写程序代码非常简洁,几句代码就是一个独立可运行的程序,下面我们直接上代码演示一下。
一个示例可以看到 aardio 窗口嵌入 .Net 控件有多简单:
import win.ui;
var winform = win.form(text="DataGridView")
import System.Data;
var tab = System.Data.DataTable("DT");
tab.Columns.Add("名称");
tab.Rows.Add({"WangWu"});
import System.Windows.Forms;
var grid = System.Windows.Forms.CreateEmbed("DataGridView",winform);
grid.ColumnHeadersHeightSizeMode = 2;
grid.DataSource = System.Data.DataView(tab);
winform.show();
win.loopMessage();
下面演示一下用 aardio 调用 PowerShell,并且在 PowerShell 中调用 aardio。这甚至都不用带上体积较大的 System.Management.Automation.dll,一个轻巧的 EXE 就可以搞定一切,向下兼容到 PowerShell 2.0。 var pScript = /*
# 声明 PowerShell 参数
param($win)
# 修改 aardio 对象属性
$win.title = "owerShell + aardio";
# 调用 aardio 对象函数
$win.msgbox("这是 PowerShell 调用 aardio 打开的对话框。")
*/
import win;
dotNet.ps(pScript,{
win = win; //# 将 aardio 对象作为参数传给 PowerShell
});
aardio 直接调用系统 API 函数:
import console;
//不需要声明,直接调用原生 API 函数,语法简洁可读性好。
var result = ::User32.PtInRect( ::RECT(2,3,300,500) , 12, 66 );
console.log( result );
console.pause(true);
将任何网络 API 甚至是任意普通网址声明为 aardio 对象: import web.rest.jsonLiteClient;
var http = web.rest.jsonLiteClient();
//导入远程 API
var countApi = http.api("https://api.countapi.xyz/hit{/domain}{/key}")
//服务器 API 已经变成了 aardio 函数对象
var data = countApi["key"].get();
编译 C 语言代码生成 DLL 执行文件,再调用 DLL 中的 C 函数: import tcc;
//编译 DLL
tcc.build( "/start.dll" ).code = /***
#include <windows.h>
__declspec(dllexport) int Add( int a,int b )
{
return a + b;
}
***/
//加载 DLL
var dll = raw.loadDll( "/start.dll",,"cdecl" );
//调用 C函数
var result = dll.Add(12,3);
屏幕找字: import mouse;
import string.ocrLite;
import string.ocrLite.defaultModels;
var ocr = string.ocrLite();
var ocrResult = ocr.detectScreen();
var x,y = ocrResult.findPoint("要查找的按钮文本",0.1);
mouse.moveTo(x,y,true);
在 aardio 中调用 Python,简单得就像在 Python 中使用 Python: import console;
import py3;
//导入 Python 模块。
var itertools = py3.import("itertools")
//调用 Python 函数,支持纯 aardio 类型参数
var permutations = itertools.permutations({"a","b","c"});
//调用 Python 内置函数 list
var pyList = py3.list(permutations);
//遍历 Python 对象成员
for( item in pyList.each() ){
console.log(item); //像 aardio 对象一样使用 Python 对象
}
console.pause();
播放 GIF 动画: import win.ui;
/*DSG{{*/
var winform = win.form(text="GIF 动画";bgcolor=0xEDDDD8)
winform.add(
plus={cls="plus";left=0;top=0;right=760;bottom=470;repeat="scale";z=1}
)
/*}}*/
import inet.http;
winform.plus.background = "http://download.aardio.com/v10.files/demo/plus-demo.gif";
winform.show();
win.loopMessage();
调用微软 WebView2 控件截图: import win.ui;
/*DSG{{*/
var winform = win.form(text="WebView2 网页截图";right=1108;bottom=759)
/*}}*/
import web.view;
var wb = web.view(winform,,0/*自动调试端口*/);
winform.show();
wb.go("http://www.baidu.com");
wb.wait("baidu");
import web.socket.chrome;
var ws = wb.openRemoteDebugging();
ws.Runtime.enable();//启用 Runtime.executionContextCreated
//截图
import crypt;
import process.imageView;
ws.Page.captureScreenshot().end = function(result,err){
if(result[["data"]]){
string.save("/screenshot.png",crypt.decodeBin(result[["data"]]) )
process.imageView("/screenshot.png");
}
}
win.loopMessage();
获取系统 TPM 版本信息: import console;
import sys.tpmInfo;
var tpmInfo = sys.tpmInfo.get();
if(tpmInfo){
console.log("支持 TPM");
console.log("TPM 是否启用:",tpmInfo.enabled);
console.log("TPM 是否激活:",tpmInfo.activated);
console.log("TPM 支持版本:",tpmInfo.version)
}
else {
console.log("不支持 TPM");
}
console.pause();
查看系统安装序列号: import com.wmi;
import win.reg;
var productKey = com.wmi.get("softwarelicensingservice","OA3xOriginalProductKey");
if(!productKey) {
productKey = win.reg.queryWow64( "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SoftwareProtectionPlatform","BackupProductKeyDefault" )
}
import console;
console.log("安装序列号" ,productKey);
console.pause(true);
调用 .Net 创建 WebService: import console;
import dotNet;
//创建应用程序域(无参数创建唯一实例,不必手动释放)
var appDomain = dotNet.appDomain();
//动态创建Web服务
var webService = appDomain.createWebService("http://fy.webxml.com.cn/webservices/EnglishChinese.asmx")
//调用WebService接口创建类
var englishChinese = webService.createInstance("EnglishChinese")
//调用WebService提供的函数
var ret = englishChinese.TranslatorString("hello" );
console.dump(ret);
console.pause();
其实不用调用 .Net ,纯 aardio 代码调用 WebService 更简单,。
以前研究过 MSSOAP ,要依赖一堆 DLL 文件,这不符合 aardio 的风格。所以我自己研究了一下 SOAP 协议写了个 web.soapClient , 几句代码搞定,不依赖任何外部组件:
import console;
//导入MSSOAP支持库
import web.soapClient;
//创建SOAP客户端
seviceClient = web.soapClient("http://fy.webxml.com.cn/webservices/EnglishChinese.asmx")
//调用远程Web服务提供的函数
var transArray,err = seviceClient.TranslatorString("hello");
//显示返回值
console.dump( string.join( transArray,'\r\n' ) ) ;
//按任意键继续
console.pause();
在 aardio 中嵌入并调用批处理: import console
import process.batch;
//批处理 for 遍历并拆分字符串
var bat = process.batch(`
@echo off
for %%i in (abc,def,xyz) do echo %%i
`)
console.log(bat.read(-1))
console.pause()
调用命令行,并自动触发 Ctrl + C :
import console
import process.popen
var prcs = process.popen("ping 127.0.0.1 -n 10 ")
for( all,out,err in prcs.each() ){
console.log( out,err );
prcs.ctrlEvent(0);
}
console.pause();
调用 Rust 语言解析 TOML :
import console;
import string.toml;
var str = string.toml.stringify({abc=123,d={1,2,3}});
console.log( str );
import process.code;
process.code("~\lib\string\toml\.res");
console.pause(true);
在 aardio 里嵌入 PHP,以下短短几句代码,包含了 HTTP 服务器,PHP服务端,嵌入的浏览器组件: import win.ui;
/*DSG{{*/
var winform = win.form(text="Hello World / PHP_CGI 服务器")
/*}}*/
var code = /*
<html>
<head>
<meta charset="utf-8">
<title>HP 测试</title>
</head>
<body>
<?php echo '<p>Hello World / PHP_CGI 服务器</p>'; ?>
</body>
</html>
*/
string.save("/test.php",code);
import php.simpleHttpServer;
var url = php.simpleHttpServer.startUrl("/test.php");
import web.form;
var wb = web.form(winform);
wb.go(url);
winform.show();
win.loopMessage();
执行 Ruby 语言代码: import win.ui;
/*DSG{{*/
var winform = win.form(text="执行Ruby代码")
winform.add(
edit={cls="edit";left=26;top=16;right=737;bottom=435;multiline=1;z=1}
)
/*}}*/
import process.ruby;
var out = process.ruby.exec("puts '测试UTF-8'")
winform.edit.print(out);
var out = process.ruby.eval(`[1, 2, { name: "tanaka", age: 19 }]`)
winform.edit.print(out);
winform.show();
win.loopMessage();
|