前面帖子里的示例也已经更新。 本帖最后由 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:46 编辑
我还以为只能编译为exe文件,这样就跟c#一样了。不对,还是通过exe调用dll文件与lisp交互,这样的好处是什么呢? 本帖最后由 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 总的来说都是好事,你选择适合你的方案就可以。
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:07 编辑
jacenhe 发表于 2022-2-13 07:45
不错,你的建议非常好。随手拿这个 C# 代码小试了一下,为了省事直接在 aardio 里编译 C# 为 DLL,然后自 ...
这玩意还可以这样调用命令cad.SendCommand,感觉比调用控件方便些,控件win10有些不能注册 jun353835273 发表于 2022-2-14 09:06
这玩意还可以这样调用命令cad.SendCommand,感觉比调用控件方便些,控件win10有些不能注册
aardio 里注册 COM 控件比较简单,不需要管理权限,可以用代码自动注册。
一般不会出现不能注册控件的问题,而且很多 COM 控件在 aardio 里都可以免注册调用。
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 接口,那外部文件也可以省了。
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