jacenhe 发表于 2022-2-13 04:14:41

今天改进了 aardio 标准库中的 com.cad 以及调用范例, LISP 调用 aardio 、aardio 调用 LISP 都更简单了。
前面帖子里的示例也已经更新。

jacenhe 发表于 2022-2-13 07:45:31

本帖最后由 jacenhe 于 2024-6-3 15:31 编辑

jun353835273 发表于 2021-6-1 13:05
c#的交互要方便的多
http://bbs.mjtd.com/thread-180931-1-1.html
不错,你的建议非常好。随手拿这个 C# 代码小试了一下,为了省事直接在 aardio 里编译 C# 为 DLL,然后自动并加载到 AutoCAD,然后再在 aardio 里调用 AutoCAD 再调用这个 C# 写的 DLL:
import console;
console.showLoading("正在编译 .NET DLL");

import dotNet;
import com.cad;

//创建 AutoCAD 对象
var cad = com.cad();
cad.Visible = true;

//创建 C# 语言编译器
var compiler = cad.NetCompiler("C#");

compiler.Source = /******
using System;
using System.Collections.Generic;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using Wnd = System.Windows.Forms;

public class TestFunctions
{
         
         public static ResultBufferListfunSelfiles(ResultBuffer DataIn)
         {
             ResultBuffer Ret = new ResultBuffer();
             if (DataIn == null) return null;
             TypedValue[] Tranlisp = DataIn.AsArray();
             try
             {
               if (Tranlisp.Length == 2)
               {
                     string Title = Tranlisp.Value as string;
                     string Filter = Tranlisp.Value as string;
                     string FilterIn = "(*." + Filter + ")|*." + Filter;
                     Wnd.OpenFileDialog openDlg = new Wnd.OpenFileDialog();
                     openDlg.Title = Title;
                     openDlg.Filter = FilterIn;
                     openDlg.Multiselect = true;
                     Wnd.DialogResult openRes = openDlg.ShowDialog();
                     if (openRes == Wnd.DialogResult.OK)
                     {
                         string[] strNames = openDlg.FileNames;
                         for (int i = 0; i < strNames.Length; i++)
                         {
                           Ret.Add(new TypedValue((int)LispDataType.Text, strNames[ i ]));
                         }
                     }
                     else
                     {
                         return null;
                     }
               }
             }
             catch (Autodesk.AutoCAD.Runtime.Exception)
             {
               return null;
             }
             return Ret;
         }
}

******/

var assembly = compiler.Compile("/ListfunSelfiles.dll"); //编译并返回程序集
console.log(compiler.getLastError()); //查看编译器错误信息

cad.NetLoad("/ListfunSelfiles.dll");
cad.SendCommand(`(ListfunSelfiles"打开文本" "txt")`);

console.pause();




liuyj 发表于 2022-2-13 10:33:22

本帖最后由 liuyj 于 2022-2-13 10:46 编辑

我还以为只能编译为exe文件,这样就跟c#一样了。不对,还是通过exe调用dll文件与lisp交互,这样的好处是什么呢?

jacenhe 发表于 2022-2-13 14:26:46

本帖最后由 jacenhe 于 2022-2-13 14:32 编辑

liuyj 发表于 2022-2-13 10:33
我还以为只能编译为exe文件,这样就跟c#一样了。不对,还是通过exe调用dll文件与lisp交互,这样的好处是什 ...
我没说 aardio 是通过 DLL 文件与 LISP 交互.
我只是发了个 aardio 调用 C# 生成并调用 DLL 的例子,能这样做 -不等于必须这样做,能理解吧?!
关于你说的通过 EXE 交互,我写了 3 个例子,都是使用 EXE( 并不是你说的DLL )。

至于你说的 "好处是什么 ?"
你的问题就是让我 ”多发几个 aardio 与 LISP 交互的例子“,
所以,我”多发了几个 aardio 与 与 LISP 交互的例子“,按你的要求多发几个例子,多几个选择有什么不好吗?
更多语言、更多方案可以支持 AutoCAD 总的来说都是好事,你选择适合你的方案就可以。



jacenhe 发表于 2022-2-13 14:31:41

LISP 调用 aardio 的三种方法

LISP 调用 aardio 的三种方法
http://bbs.mjtd.com/forum.php?mod=redirect&goto=findpost&ptid=183478&pid=891650&fromuid=7328233

jun353835273 发表于 2022-2-14 09:06:35

本帖最后由 jun353835273 于 2022-2-14 09:07 编辑

jacenhe 发表于 2022-2-13 07:45
不错,你的建议非常好。随手拿这个 C# 代码小试了一下,为了省事直接在 aardio 里编译 C# 为 DLL,然后自 ...
这玩意还可以这样调用命令cad.SendCommand,感觉比调用控件方便些,控件win10有些不能注册

jacenhe 发表于 2022-2-14 12:36:47

jun353835273 发表于 2022-2-14 09:06
这玩意还可以这样调用命令cad.SendCommand,感觉比调用控件方便些,控件win10有些不能注册

aardio 里注册 COM 控件比较简单,不需要管理权限,可以用代码自动注册。
一般不会出现不能注册控件的问题,而且很多 COM 控件在 aardio 里都可以免注册调用。

jacenhe 发表于 2022-2-14 12:43:41


aardio 提供的 cad.SendCommand() ,cad.LoadLisp()可以执行 LISP 代码,还能支持 aardio 的模板语法,
也就是可以将 LISP 代码与 aardio 代码混写,这有一点像 PHP 与 HTML 可以混写。例如:

cad.SendCommand(`
(setq c:hello nil)
(defun c:hello(/ name)
(set 'name (getstring "What's your name? "))
(set 'msg (strcat "Hello, " name <?= time(),"这是 aardio 对象" ?>))
(write-line msg))
hello`)


上面蓝色部分就是 aardio 代码,用这个方法就可以做很多事了,例如把 EXE 自身路径传给 LISP,就不再需要用 LISP 编码解码 EXE 的二进制数据了,速度可以大幅提升。


EXE 启动时就可以做太多事了,例如用 cad.LoadLisp() 加载 LISP 代码或 LISP 文件。可以用 cad.NetLoad 加载 C# 写的 DLL。都能自动识别版本,在需要时设置 SECURELOAD 开启并恢复权限、静默加载,不会弹出警告。


aardio 可以非常方便地打包外部文件生成独立 EXE 文件。
外部文件可以直接放到工程资源目录下 —— 通过 string.load("/res/xxxx") 函数加载。
也可以在文件路径前加一个 $ 将文件的二进制数据直接编译到程序里 —— 例如:$"/xxx/xxx.dll"。并且可以用io.appData("xxx/xxx.dll", $"/xxx/xxx.dll") 运行时释放到 AppData 目录返回路径。

当然如果只是使用cad.SendCommand() 这些 COM 接口,那外部文件也可以省了。





yu960312 发表于 2023-12-10 21:33:36

jacenhe 发表于 2022-2-12 12:08
@liuyj
这里说的是在 lisp 里调用 EXE ,如果你没传参数,直接双击运行 EXE,就会出现你那个错误。




import io;
import win;
//自标准输入读取 LISP 传入的值
var hwnd = io.stdin.read("%d");
win.msgbox(hwnd);
/////////////////////////////////
以上代码生成exe后执行【(startapp "D:/CAD.exe" (strcat "/hwnd" " " (itoa(vla-get-hwnd(vlax-get-acad-object)))))】
并没有把CAD窗口句柄传递给exe
页: 1 2 [3]
查看完整版本: 我也来发一个多文件选择对话框,lisp+aardio实现